您的位置:首页 > 移动开发 > Android开发

Android ListView中子控件的状态保存以及点击子控件改变子控件状态

2014-11-19 10:20 357 查看
这两天用到了ListView,写下遇到的一些问题。首先是ListView本身与子控件的焦点问题,比如我这里子控件用到了Button,在需要ListView中的根布局属性上加上下面的这一个属性:

[html] view
plaincopy





android:descendantFocusability="blocksDescendants"

用于屏蔽子控件抢夺ListView的焦点,也可在Button本身设置焦点属性为false。其它的一些控件的点击问题就不说了,网上有很多。

然后是需要点击Button进行网络操作,返回正确结果后设置Button的test为"XXX",我这里不需要设置其它控件状态改变了,处理方法除了下面我的方法外,也可以用selector。此外还需要保存每个item的position位置用来保存Button的状态(应该这么说:记录此Item(position)上Button的状态,因为是在getView方法里去判断Button状态来设置的,所以叫记录比较好吧),这个问题需要细心的处理,不然就会出现只点击第一个Button后,后面position的Button也被设置成了“XXX”,还有Button的设置的setClickable也会有问题。

好吧,不说了,下面是写的代码, 代码里我应该写的挺清楚的了。这里只是ListView的布局,还有Adapter的代码。要用的话自己在一个Activity的布局里加上个ListView控件,再在代码里设置listview的adapter就可以用了。

ListView的布局

[html] view
plaincopy





<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:descendantFocusability="blocksDescendants"

android:orientation="horizontal" >



<LinearLayout

android:layout_width="0dp"

android:layout_height="match_parent"

android:layout_weight="1"

android:gravity="center"

android:orientation="vertical" >



<TextView

android:id="@+id/txt_pre_entry_class"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:singleLine="true"

android:text="test" />

</LinearLayout>



<LinearLayout

android:layout_width="0dp"

android:layout_height="match_parent"

android:layout_weight="2"

android:gravity="center"

android:orientation="vertical" >



<TextView

android:id="@+id/txt_pre_entry_teacher"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:singleLine="true"

android:text="Txt1" />



<TextView

android:id="@+id/txt_pre_entry_course"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:singleLine="true"

android:text="Txt2" />



<TextView

android:id="@+id/txt_pre_entry_class_name"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:singleLine="true"

android:text="Txt3" />

</LinearLayout>



<LinearLayout

android:layout_width="0dp"

android:layout_height="match_parent"

android:layout_weight="1"

android:gravity="center"

android:orientation="vertical" >



<Button

android:id="@+id/btn_pre_entry_order"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:singleLine="true"

android:background="@drawable/button_rounded"

android:text="未预约"

/>

</LinearLayout>



</LinearLayout>

ListView的Adapter

[java] view
plaincopy





public class PreEntryAdapter extends BaseAdapter

{

private LayoutInflater inflater;

private Context context;

private Dialog orderDialog;

private String summitUrl;

private Handler orderHandler;

private viewHolder holder;

OrderAsyncTask orderAsyncTask;

List<List> listSize, listList;

TextView txtClass, teacherName, className, courseName;

//当前的位置,这个很重要,Button的状态记录就靠它了

private int currentPosition = 0;

//这个Button用于在重网络返回数据后设置其显示的内容,如成功、失败等。

private Button currentBtn;

//这个数组参数是记录每个position上的Button的请求是否成功

private boolean[] ORDER_SUCCESS;

//这是我用来填充假数据的

private String[] classes;





/**

* 这里后面两个参数是我要填充的数据,子控件的显示内容就由listList得到

*/

public PreEntryAdapter(Context context, List<List> listSize, List<List> listList)

{

this.context = context;

this.listSize = listSize;

this.listList = listList;

ORDER_SUCCESS = new boolean[30];// int[listSize.get(0).get(0)];

classes = new String[30];

for (int i = 0; i < 30; i++)

{

classes[i] = "教2-" + i;

}

initView();

}





private void initView()

{

inflater = LayoutInflater.from(context);

orderDialog = new Dialog(context);

View view = inflater.inflate(R.layout.dialog_evaluate_order_preentry, null);

orderDialog.setContentView(view);

orderDialog.setCancelable(false);

orderDialog.setTitle("提交");

}





@Override

public int getCount()

{

//这里先设有30条Item数据

return 30;// listSize.get(0).get(0);

}





@Override

public Object getItem(int position)

{

return position;

}





@Override

public long getItemId(int position)

{

return position;

}





@Override

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

{

Log.v("log", "--->getView()-" + position);

if (convertView == null)

{

holder = new viewHolder();

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





holder.btn_order = (Button) convertView.findViewById(R.id.btn_pre_entry_order);

holder.txt_class = (TextView) convertView.findViewById(R.id.txt_pre_entry_class);

holder.txt_class_name = (TextView) convertView.findViewById(R.id.txt_pre_entry_class_name);

holder.txt_course = (TextView) convertView.findViewById(R.id.txt_pre_entry_course);

holder.txt_teacher = (TextView) convertView.findViewById(R.id.txt_pre_entry_teacher);





convertView.setTag(holder);

}

else

{

holder = (viewHolder) convertView.getTag();

}

Log.v("log", "-->getView()--ORDER_SUCCESS[" + position + "]-" + ORDER_SUCCESS[position]);

// 判断保存的position位置上的Butoon是否已预约成功

if (ORDER_SUCCESS[position])

{

holder.btn_order.setText("已预约");

// 这里不设的话返回来时还会可点击,因为向下拉时,Holder里的btn被设置成可点击了

// holder.btn_order.setEnabled(false);

holder.btn_order.setClickable(false);

}

else

{

// 这里要写上默认的显示内容,要不然后面的子控件会出现显示已预订的情况。因为不设置的话btn还是Holder中的btn,而此时holder中的btn是已经设置了已预约的

holder.btn_order.setText("未预约");

// 要设置为可点击,不然是Holder里的状态

// holder.btn_order.setEnabled(true);

holder.btn_order.setClickable(true);

// 这个也要放这里判断

holder.btn_order.setOnClickListener(new btnListener(position, holder.btn_order));

}

// 课室假数据

holder.txt_class.setText(classes[position]);

/*

* holder.txt_class.setText((CharSequence)

* listList.get(position).get(4)); //

* holder.txt_class_name.setText(listList.get(position).get()); //

* holder.txt_course.setText((CharSequence)

* listList.get(position).get(2)); //

* holder.txt_teacher.setText((CharSequence)

* listList.get(position).get(3));

*/





return convertView;

}





/**

* 要传入当前点击的Button,用于设置currentBtn为当前点击的Button,这样点击后的setText就不会错位了。

*/

class btnListener implements OnClickListener

{

private int position;

private Button Btn;





public btnListener(int position, Button currentBtn)

{

this.position = position;

this.Btn = currentBtn;

}





@Override

public void onClick(View v)

{

currentPosition = position;

currentBtn = Btn;

Toast.makeText(context, "点击第 " + (position + 1) + "个Button", 0).show();

orderAsyncTask = new OrderAsyncTask();

orderAsyncTask.execute("");

orderDialog.show();

}





}





private static class viewHolder

{

private Button btn_order;

private Button btn_temp;

private TextView txt_class, txt_teacher, txt_course, txt_class_name;





}





/**

* 异步AsyncTask

*/

private class OrderAsyncTask extends AsyncTask<String, Integer, Integer>

{





@Override

protected void onPreExecute()

{

super.onPreExecute();

}





// 异步处理

@Override

protected Integer doInBackground(String... nullNow)

{

Log.v("log", "-->doInBackground()--params-" + nullNow[0]);

try

{

Thread.sleep(2500);

return SubmitHandler.submitOrder((String) listList.get(currentPosition).get(0), (String) listList

.get(currentPosition).get(1), (String) listList.get(currentPosition).get(5),

Edu_Survey_OrderInfo.ORDER_WEEK);





}

catch (Exception e)

{

e.printStackTrace();

Log.v("log", "-->doInBackground() ERROR!");

}

return 0;

}





@Override

protected void onProgressUpdate(Integer... values)

{

super.onProgressUpdate(values);

}





@Override

protected void onPostExecute(Integer responseCode)

{

Log.v("log", "-->responseCode-" + responseCode);

//先假设已经请求成功了

responseCode = 200;

switch (responseCode)

{

case 200:

ORDER_SUCCESS[currentPosition] = true;

currentBtn.setText("已预约");

// 这里不设的话在当前页面下currentBtn一直可点击,因为getView里设的话是要调用getView时才能起作用的。

// currentBtn.setEnabled(false);

currentBtn.setClickable(false);

break;

case 404:

break;

default:

break;

}





Log.v("log", "-->onPostExecute()--currentPosition-" + currentPosition);

Log.v("log", "-->onPostExecute()--ORDER_SUCCESS[" + currentPosition + "]-"

+ ORDER_SUCCESS[currentPosition]);

orderDialog.dismiss();

super.onPostExecute(responseCode);

}





}





}

效果图:





补充:
Button可以设置tag来唯一标记它,之后就可以通过listview.findViewWithTag(tag)找到了。不需要上面这么麻烦。

转自:http://blog.csdn.net/bbld_/article/details/24590345
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐