Android / Java - 如何在 listView 中找到微调器所在的行

Posted

技术标签:

【中文标题】Android / Java - 如何在 listView 中找到微调器所在的行【英文标题】:Android / Java - How can I find the row in which a spinner is contained in a listView 【发布时间】:2021-03-26 11:41:48 【问题描述】:

我有一个 listView,其中每一行都包含一个 textView 和一个 Spinner。我可以同时填充两者,并且可以毫无问题地从 Spinner 中进行选择。当用户从微调器中选择时,我可以使用 onItemSelected() 读取选择。

我的问题是我不知道如何识别 listView 中的哪一行被选中。

我尝试过使用 setTag() 和 setId(),但无法让它们中的任何一个满足我的需要。

我还尝试在该行上方放置一个透明按钮并使用 onClickListener,但该按钮会遮挡微调器,因此您实际上不会激活微调器。

下面是我的代码。我将不胜感激任何帮助或正确方向的指示。

我已经查看了数十篇关于 SO 的相关帖子,但找不到真正回答这个问题的帖子。如果我错过了,请道歉。

谢谢

适配器中 getView() 的代码。

public class AdapterSelectEventPayment extends BaseAdapter 

    private ArrayList<String> mSpinnerItems;
    private ArrayList<String> mDataSource;

    private Context mContext;
    private AdapterView.OnItemSelectedListener mSpinnerItemSelectedListener;

    public AdapterSelectEventPayment(ArrayList<String> data, ArrayList<String> spinnerItems, Context context) 
        mDataSource = data;
        mContext = context;
        mSpinnerItems = spinnerItems;
    

    @Override
    public int getCount() 
        return mDataSource.size();
    

    @Override
    public Object getItem(int position) 
        return mDataSource.get(position);
    

    @Override
    public long getItemId(int position) 
        return 0;
    


    @Override
    public View getView(int position, View convertView, ViewGroup parent) 
        View view = convertView;
        if (view == null) 
            LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            view = inflater.inflate(R.layout.select_event_charge_items, null);
        

        TextView textView = (TextView) view.findViewById(R.id.row_item_textview);
        Spinner spinner = (Spinner) view.findViewById(R.id.row_item_spinner);

        textView.setText(mDataSource.get(position));
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(mContext, android.R.layout.simple_spinner_dropdown_item, mSpinnerItems);
        spinner.setAdapter(adapter);
        spinner.setTag(position);

        spinner.setOnItemSelectedListener(mSpinnerItemSelectedListener);

        return view;
    

    public void setOnSpinnerItemSelectedListener(AdapterView.OnItemSelectedListener listener)
        this.mSpinnerItemSelectedListener = listener;
    



主活动中的代码

private void sortArrayList() 
        
            AdapterSelectEventPayment adapter = new AdapterSelectEventPayment(participants, chargeArray, this);

            adapter.setOnSpinnerItemSelectedListener(new AdapterView.OnItemSelectedListener() 
                @Override
                public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) 
                    System.out.println("The spinner has been spun... and position is " + position + " and the id = " + id);
                    System.out.println("Tag is " + selectedItemView.getTag());
                

                @Override
                public void onNothingSelected(AdapterView<?> parentView) 
                    System.out.println("The spinner has NOT been spun...");
                
            );

            lvSpinner.setAdapter(adapter);
    

【问题讨论】:

我看到您的适配器 mSpinnerItemSelectedListener 中有一个微调器监听器,但您的活动有一个不同的微调器监听器。你能解释一下吗? 你能发布你的适配器类的全部内容吗?我认为您可能错过了一个重要的onItemClickListener,其中包含项目点击的位置。 感谢您的回复。我已经发布了完整的适配器。侦听器名称的差异仅取决于它的定义方式,但它的工作原理是在使用它时会触发主活动中的 onItemSelected()。 @WarrenHarding 你能在parentView而不是selectedItemView上做getTag并检查一下吗? @akhilnair 就是这样。太感谢了。我应该自己想出来的——但我已经看了好几个小时了。再次感谢你的帮助。 (不知道我怎么能支持你的答案)。 【参考方案1】:

不要在selectedItemView上调用getTag,而是在parentView上调用它

【讨论】:

【参考方案2】:

我建议您创建一个界面,使用 Spinner 选择中的所有相关信息 + 被点击项目的位置回调您

interface ListSpinnerListener() 
    void onSpinnerItemSelected(int rowPos, int selectedItemPos, ...);

您的 Activity 可以分配您分配 AdapterView.OnItemSelectedListener 的方式,而是直接在您内部使用该侦听器 getView() 方法

适配器:

private ListSpinnerListener listSpinnerListener;

...

@Override
public View getView(int position, View convertView, ViewGroup parent) 
    View view = convertView;
    if (view == null) 
        LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        view = inflater.inflate(R.layout.select_event_charge_items, null);
    

    TextView textView = (TextView) view.findViewById(R.id.row_item_textview);
    Spinner spinner = (Spinner) view.findViewById(R.id.row_item_spinner);

    textView.setText(mDataSource.get(position));
    ArrayAdapter<String> adapter = new ArrayAdapter<String>(mContext, android.R.layout.simple_spinner_dropdown_item, mSpinnerItems);
    spinner.setAdapter(adapter);
    spinner.setTag(position);

    spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() 
        @Override
        public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int itemPosition, long id) 
            System.out.println("The spinner has been spun... and position is " + position + " and the id = " + id);
            System.out.println("Tag is " + selectedItemView.getTag());
            listSpinnerListener.onSpinnerItemSelectedListener(position, itemPosition, ...);
        

        @Override
        public void onNothingSelected(AdapterView<?> parentView) 
            System.out.println("The spinner has NOT been spun...");
        
    );

    return view;

通过这种方式,您可以确保通过一个简单的界面始终获得所需的所有相关信息,而无需通过标签等破解答案。

【讨论】:

谢谢你。这是有道理的,我会试一试。有什么地方我应该特别定义接口吗?谢谢 这完全取决于您。我使用了一个单方法接口,如果你喜欢的话,它可以用 Java 8 和/或 Kotlin 转换成 lambda。但实际上,您可以完全控制这个类,您应该根据自己的具体需求来实现它。 再次感谢您的帮助。

以上是关于Android / Java - 如何在 listView 中找到微调器所在的行的主要内容,如果未能解决你的问题,请参考以下文章

java #android #broadcast list

Android Gems - Java源码分析之List

Android Gems - Java源码分析之List

如何在 Android 中使用 Parcelable 读取 List<List<List<Double>>

如何从Android中的图像数组创建视频?

JAVA/ANDROID 数组转换为LIST