【问题标题】:Iterate through ListView in custom Adapter遍历自定义 Adapter 中的 ListView
【发布时间】:2015-03-21 19:04:43
【问题描述】:

我有一个自定义ListView。每行包含一个TextViewImageView

看截图:

在项目上单击我使 ImageView 可见。但问题是一次只能看到一个ImageView

我认为最好的方法是在点击时将所有其他ImageViews 设置为INVISIBLE。在所有图像消失之后,点击一个VISIBLE

但我不知道如何在Adapter 中正确迭代:

    private class TimeZoneItemAdapter extends ArrayAdapter<String> {
    private Activity myContext;
    private ArrayList<String> datas;


    public TimeZoneItemAdapter(Context context, int textViewResourceId, ArrayList<String> objects) {
        super(context, textViewResourceId, objects);

        myContext = (Activity) context;
        datas = objects;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        final ViewHolder viewHolder;
        if (convertView == null) {
            LayoutInflater inflater = myContext.getLayoutInflater();

            convertView = inflater.inflate(R.layout.listview_item, null);

            viewHolder = new ViewHolder();
            viewHolder.postNameView = (TextView) convertView.findViewById(R.id.listview_item);
            viewHolder.postImageView = (ImageView) convertView.findViewById(R.id.image_mark);

            convertView.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }
        viewHolder.postNameView.setText(datas.get(position));

        viewHolder.postNameView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //clear all image views during iteration
                View view;
                for (int i = 0; i < datas.size(); i++) {
                    //dont know which parameter need there for proper iteration
                    view = getView(i, ?????, null);
                    ImageView image = (ImageView) view.findViewById(R.id.image_mark);
                    image.setVisibility(View.INVISIBLE);
                }

                if (viewHolder.postImageView.getVisibility() != View.VISIBLE) {
                    selectedTimeZone = viewHolder.postNameView.getText().toString();
                    viewHolder.postImageView.setVisibility(View.VISIBLE);
                } else {
                    viewHolder.postImageView.setVisibility(View.INVISIBLE);
                }
            }
        });
        return convertView;
    }

    class ViewHolder {
        TextView postNameView;
        ImageView postImageView;
    }
}

请帮助我或提供一些提示。我真的很困惑。

【问题讨论】:

  • 为你的行设置标签并尝试让 imageview 可见
  • 我建议您为您的列表创建一个自定义对象,并选择一个字符串数据和一个布尔值。默认情况下将 selected 实例化为 false,单击 imageview 时实例化为 true。执行此操作时,您还将所有其他选择的对象参数设置为 false。

标签: android android-layout android-listview android-adapter


【解决方案1】:

有一个解决方案:

private static View lastClicked = null;

... ...

viewHolder.postNameView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            View parentRow = (View) v.getParent();
            ViewHolder viewHolder = (ViewHolder)parentRow.getTag();

            if(viewHolder.postImageView.getVisibility() != View.VISIBLE) 
            {
                //clear last clicked image
                if(lastClicked != null)
                {
                   ViewHolder lastHolder = (ViewHolder)lastClicked.getTag();
                   lastHolder.postImageView.setVisibility(View.INVISIBLE);
                }

                selectedTimeZone = viewHolder.postNameView.getText().toString();
                viewHolder.postImageView.setVisibility(View.VISIBLE);
                lastClicked = parentRow;
            } 
            else 
            {
                viewHolder.postImageView.setVisibility(View.INVISIBLE);
                lastClicked = null;
            }

    });

希望对您有所帮助!

【讨论】:

  • 我喜欢这种方法,但是在以下行有错误:ViewHolder lastHolder = (ViewHolder)lastClicked;。不可转换的类型ViewViewHolder
  • 抱歉我写的太匆忙有错误,现在修改一下。 getTag() 不见了
  • 哦...,您接受了一个答案?我想我的解决方案更好
  • 你能给出理由吗?他首先给出了解决方案,所以我将其标记为正确。但如果你证明你的方法更好,我会改变接受的答案。我猜那是公平的
  • When clicking on an item, you should iterate the datas, *uncheck everything* and check the appropriate item.,您认为这是一个好的解决方案吗?在我的解决方案中,最后点击的图像不可见。
【解决方案2】:

在 onClick 中,您正在遍历视图并确保它们都隐藏了图像,然后将当前的图像设置为可见。你不需要自己做,只需要告诉系统为你做。

还请注意,您当前的代码将围绕适配器中的所有条目循环并尝试为它们获取视图...但并非所有条目都具有视图,滚动到屏幕外的条目将没有视图。

最简单的方法是从您的 onClick 处理程序中删除除您设置selectedTimeZone 的行之外的所有内容,然后调用notifyDataSetChanged()。这将使 Android 重绘所有当前屏幕上的视图。

然后在您的setText() 下方添加:

if (datas.get(position).equals(selectedTimeZone)) {
   viewHolder.postImageView.setVisibility(View.VISIBLE);
} else { 
   viewHolder.postImageView.setVisibility(View.INVISIBLE);
}

因此,当系统重新绘制视图时,每个视图都将被视为将图像设置为可见,但只有当前视图会对其进行设置。

【讨论】:

    【解决方案3】:

    我不会存储有关视图的任何信息。我相信列表视图会回收其视图,因此事情可能会变得混乱。尝试将数据与视图分开。

    我会尝试不同的方法。你的datas 应该是

    ArrayList<MyData> datas;
    
    public class MyData{
        String place;
        boolean: checked = false;
    }
    

    要填充datas ArrayList,您可以这样做

    for (String s : objects){
        MyData d = new MyData();
        d.place = s;
    }
    

    然后在您的适配器 getView 中,您应该根据 checked 的值显示/隐藏 imageView,如下所示:

    private class TimeZoneItemAdapter extends ArrayAdapter<MyData> {
        private Activity myContext;
        private ArrayList<MyData> datas;
    
    
        public TimeZoneItemAdapter(Context context, int textViewResourceId, ArrayList<MyDatas> datas) {
            super(context, textViewResourceId, datas);
            this.datas = datas;
        }
    
        public View getView(int position, View convertView, ViewGroup parent) {
            if (convertView == null) {
                LayoutInflater inflater = myContext.getLayoutInflater();
                convertView = inflater.inflate(R.layout.listview_item, null);
            }
    
            TextView postNameView = (TextView) convertView.findViewById(R.id.listview_item);
            TextView postImageView = (ImageView) convertView.findViewById(R.id.image_mark);
    
            postNameView.setText(this.datas.get(position).place);
            if(this.datas.get(position).checked){
                postImageView.setVisibility(View.VISIBLE);
            }else{
                postImageView.setVisibility(View.INVISIBLE);
            }
            return convertView;
        }
    }
    

    点击一个项目时,您应该迭代datas,取消选中所有内容并选中相应的项目。然后更新你调用的listView

    ((TimeZoneItemAdapter)list.getAdapter()).notifyDataSetChanged();
    

    所有视图都会自动更新。

    【讨论】:

    • 我如何将ArrayList&lt;MyData&gt; datas;分配给参数ArrayList&lt;String&gt; objects?你能写一些更精确的代码吗?
    • @AnZ 我已经更新了我的答案。让我知道这是否有帮助
    猜你喜欢
    • 2015-03-28
    • 1970-01-01
    • 2011-11-08
    • 2011-09-24
    • 1970-01-01
    • 2015-02-03
    • 1970-01-01
    • 2019-06-05
    • 1970-01-01
    相关资源
    最近更新 更多