ListView的重用机制

今天下午coding PM提出来的需求。在编码过程中发现一个问题,后来经过查阅和思考还是解决了。跟大家分享下这个过程。

该PM的要求是展示一个listview,listview的每个item都包含一个按钮,当点击了该按钮时,按钮的文字变成已点击。



当listview的长度比较长,超过一个屏幕时,点击第1个,改变状态。往下拉动,发现第15个也是显示的“已添加”。



造成这样的原因是Android中listview得重用机制。

-------2015年7月14日更新------
重用的原因是使用了Holder模式(待验证)

在listview的重用view的原理是:将可视的view和非可视的view保存在两个数据结构中,分别指activeViews和scrapViews中,activeViews指的是,当前屏幕上显示的显示的View。scrapView是指,屏幕上不显示的View,所有activeViews都会转换成scrapViews。重用是把scrapView 传给Adapter.getView , 参数convertView 不为空就是从scrapView拿出的View。

所以第一页的activeViews转换到第二页时,就会把第15个变成已添加。虽然重用机制提高了程序的效率,但是却实现不了需求。

我的解决方法:
记录已点击的button的position存在一个list中,再在getView的方法中添加一个判断,根据position是否存在list中,做出相应显示。

完整代码如下:

public class MainActivity extends ActionBarActivity {

    private ListView mListView;

    private List<String> mList;

    private List<Integer> mListAdd;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mListView = (ListView)findViewById(R.id.list_view);
        mList = new ArrayList<String>();
        mListAdd = new ArrayList<Integer>();
        for(int i = 0; i < 20; i++){
            mList.add("第" + i + "个");
        }
        mListView.setAdapter(mAdapter);
    }

    private BaseAdapter mAdapter = new BaseAdapter(){
        @Override
        public int getCount() {
            return mList.size();
        }

        @Override
        public Object getItem(int position) {
            return mList.get(position);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(final int position, View convertView, ViewGroup parent) {

            final Holder holder;

            boolean isHave = false;

            if(convertView==null){
                convertView = getLayout();
                holder = new Holder();
                holder.txt = (TextView)convertView.findViewById(R.id.txt);
                holder.btn = (Button)convertView.findViewById(R.id.btn);
                convertView.setTag(holder);
            }else{
                holder = (Holder)convertView.getTag();
            }

            holder.txt.setText(mList.get(position));
            holder.btn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    holder.btn.setText("已添加");
                    mListAdd.add(position);
                }
            });

            //执行判断
            for(Integer integer : mListAdd){
                if(integer==position){
                    isHave = false;
                }
            }
            if (isHave){
                holder.btn.setText("已添加");
            }else{
                holder.btn.setText("添加");
            }

            return convertView;
        }
    };

    class Holder{
        TextView txt;
        Button  btn;
    }

    private LinearLayout getLayout(){
        LinearLayout mLinearLayout = new LinearLayout(MainActivity.this);
        mLinearLayout.setLayoutParams(new ListView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
        mLinearLayout.setGravity(Gravity.CENTER_VERTICAL);
        mLinearLayout.setAddStatesFromChildren(true);
        mLinearLayout.setOrientation(LinearLayout.HORIZONTAL);


        TextView mTextView = new TextView(MainActivity.this);
        LinearLayout.LayoutParams txtLayoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        mTextView.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
        mTextView.setPadding(15, 0, 0, 0);
        mTextView.setId(R.id.txt);

        Button mButton = new Button(MainActivity.this);
        LinearLayout.LayoutParams layoutParams= new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        layoutParams.leftMargin = 400;
        mButton.setLayoutParams(layoutParams);
        mButton.setText("添加");
        mButton.setGravity(Gravity.CENTER_VERTICAL);
        mButton.setId(R.id.btn);

        mLinearLayout.addView(mTextView);
        mLinearLayout.addView(mButton);

        return mLinearLayout;
    }

}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值