Iterate through ListView in custom Adapter

纵然是瞬间 提交于 2019-12-24 22:40:17

问题


I have a custom ListView. Each row contains a TextView and ImageView.

Look at screenshot:

On Item click I make that ImageView visible. But the problem is that only ONE ImageView should be visible at a time.

I think that the best approach is to set all other ImageViews as INVISIBLE on click. And after all images gone make a clicked one VISIBLE.

But I don't know how to iterate properly that in 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;
    }
}

Please help me or give some hints. I'm really confused with that already.


回答1:


There is one solution:

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;
            }

    });

Hope this help!




回答2:


In the onClick you're iterating through the views and make sure that they all have the image hidden, and then after that setting the current one visible. You don't need to do that yourself, just tell the system to do it for you.

Note also that your current code will loop around all entries in the adapter and try and get a view for them... but not all of them will have one, the ones scrolled off the screen won't have a view.

The simplest way to do it is to remove everything from your onClick handler except the line where you set selectedTimeZone, then call notifyDataSetChanged(). This will make Android redraw all of the currently-onscreen views.

Then below your setText() add:

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

so when the system re-draws the views each view will be considered for having the image set to visible but only the current one will get it set.




回答3:


I wouldn't store any information on the views. I believe that the listview recycles its views so thing could get messy. Try to separate the data from the views.

I would try a different approach. Your datas should be

ArrayList<MyData> datas;

public class MyData{
    String place;
    boolean: checked = false;
}

To populate the datas ArrayList you can do this

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

Then in your adapters getView you should display/hide the imageView based on the value of checked like this:

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;
    }
}

When clicking on an item, you should iterate the datas, uncheck everything and check the appropriate item. Then to update the listView you call

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

and all the views will be updated automatically.



来源:https://stackoverflow.com/questions/29186821/iterate-through-listview-in-custom-adapter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!