在自定义适配器中迭代ListView

时间:2015-03-21 19:04:43

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

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

看截图:

enter image description here

在项目上单击,我可以看到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;
    }
}

请帮助我或提供一些提示。我已经非常困惑了。

3 个答案:

答案 0 :(得分: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;
            }

    });

希望这有帮助!

答案 1 :(得分:1)

我不会在视图中存储任何信息。我相信listview会回收它的观点,所以事情可能会变得混乱。尝试将数据与视图分开。

我会尝试不同的方法。您的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();

并且所有视图都将自动更新。

答案 2 :(得分:1)

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

另请注意,您当前的代码将遍历适配器中的所有条目并尝试获取它们的视图...但并非所有条目都有一个,滚动屏幕的条目不会有图。

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

然后在setText()添加:

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

因此,当系统重新绘制视图时,将考虑将每个视图设置为可见,但只有当前视图才能设置它。