今天下午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;
}
}