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

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

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. 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 plain copy 在CODE上查看代码片 派生到我的代码片
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:descendantFocusability="blocksDescendants"  
  6.     android:orientation="horizontal" >  
  7.   
  8.     <LinearLayout  
  9.         android:layout_width="0dp"  
  10.         android:layout_height="match_parent"  
  11.         android:layout_weight="1"  
  12.         android:gravity="center"  
  13.         android:orientation="vertical" >  
  14.   
  15.         <TextView  
  16.             android:id="@+id/txt_pre_entry_class"  
  17.             android:layout_width="match_parent"  
  18.             android:layout_height="wrap_content"  
  19.             android:singleLine="true"  
  20.             android:text="test" />  
  21.     </LinearLayout>  
  22.   
  23.     <LinearLayout  
  24.         android:layout_width="0dp"  
  25.         android:layout_height="match_parent"  
  26.         android:layout_weight="2"  
  27.         android:gravity="center"  
  28.         android:orientation="vertical" >  
  29.   
  30.         <TextView  
  31.             android:id="@+id/txt_pre_entry_teacher"  
  32.             android:layout_width="wrap_content"  
  33.             android:layout_height="wrap_content"  
  34.             android:singleLine="true"  
  35.             android:text="Txt1" />  
  36.   
  37.         <TextView  
  38.             android:id="@+id/txt_pre_entry_course"  
  39.             android:layout_width="wrap_content"  
  40.             android:layout_height="wrap_content"  
  41.             android:singleLine="true"  
  42.             android:text="Txt2" />  
  43.   
  44.         <TextView  
  45.             android:id="@+id/txt_pre_entry_class_name"  
  46.             android:layout_width="wrap_content"  
  47.             android:layout_height="wrap_content"  
  48.             android:singleLine="true"  
  49.             android:text="Txt3" />  
  50.     </LinearLayout>  
  51.   
  52.     <LinearLayout  
  53.         android:layout_width="0dp"  
  54.         android:layout_height="match_parent"  
  55.         android:layout_weight="1"  
  56.         android:gravity="center"  
  57.         android:orientation="vertical" >  
  58.   
  59.         <Button  
  60.             android:id="@+id/btn_pre_entry_order"  
  61.             android:layout_width="wrap_content"  
  62.             android:layout_height="wrap_content"  
  63.             android:singleLine="true"  
  64.             android:background="@drawable/button_rounded"  
  65.             android:text="未预约"  
  66.             />  
  67.     </LinearLayout>  
  68.   
  69. </LinearLayout>  



ListView的Adapter

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. public class PreEntryAdapter extends BaseAdapter  
  2. {  
  3.     private LayoutInflater inflater;  
  4.     private Context context;  
  5.     private Dialog orderDialog;  
  6.     private String summitUrl;  
  7.     private Handler orderHandler;  
  8.     private viewHolder holder;  
  9.     OrderAsyncTask orderAsyncTask;  
  10.     List<List> listSize, listList;  
  11.     TextView txtClass, teacherName, className, courseName;  
  12.     //当前的位置,这个很重要,Button的状态记录就靠它了  
  13.     private int currentPosition = 0;  
  14.     //这个Button用于在重网络返回数据后设置其显示的内容,如成功、失败等。  
  15.     private Button currentBtn;  
  16.     //这个数组参数是记录每个position上的Button的请求是否成功  
  17.     private boolean[] ORDER_SUCCESS;  
  18.     //这是我用来填充假数据的  
  19.     private String[] classes;  
  20.   
  21.   
  22.     /** 
  23.      * 这里后面两个参数是我要填充的数据,子控件的显示内容就由listList得到 
  24.      */  
  25.     public PreEntryAdapter(Context context, List<List> listSize, List<List> listList)  
  26.     {  
  27.         this.context = context;  
  28.         this.listSize = listSize;  
  29.         this.listList = listList;  
  30.         ORDER_SUCCESS = new boolean[30];// int[listSize.get(0).get(0)];  
  31.         classes = new String[30];  
  32.         for (int i = 0; i < 30; i++)  
  33.         {  
  34.             classes[i] = "教2-" + i;  
  35.         }  
  36.         initView();  
  37.     }  
  38.   
  39.   
  40.     private void initView()  
  41.     {  
  42.         inflater = LayoutInflater.from(context);  
  43.         orderDialog = new Dialog(context);  
  44.         View view = inflater.inflate(R.layout.dialog_evaluate_order_preentry, null);  
  45.         orderDialog.setContentView(view);  
  46.         orderDialog.setCancelable(false);  
  47.         orderDialog.setTitle("提交");  
  48.     }  
  49.   
  50.   
  51.     @Override  
  52.     public int getCount()  
  53.     {  
  54.         //这里先设有30条Item数据  
  55.         return 30;// listSize.get(0).get(0);  
  56.     }  
  57.   
  58.   
  59.     @Override  
  60.     public Object getItem(int position)  
  61.     {  
  62.         return position;  
  63.     }  
  64.   
  65.   
  66.     @Override  
  67.     public long getItemId(int position)  
  68.     {  
  69.         return position;  
  70.     }  
  71.   
  72.   
  73.     @Override  
  74.     public View getView(final int position, View convertView, ViewGroup parent)  
  75.     {  
  76.         Log.v("log""--->getView()-" + position);  
  77.         if (convertView == null)  
  78.         {  
  79.             holder = new viewHolder();  
  80.             convertView = inflater.inflate(R.layout.adapter_preentry, null);  
  81.   
  82.   
  83.             holder.btn_order = (Button) convertView.findViewById(R.id.btn_pre_entry_order);  
  84.             holder.txt_class = (TextView) convertView.findViewById(R.id.txt_pre_entry_class);  
  85.             holder.txt_class_name = (TextView) convertView.findViewById(R.id.txt_pre_entry_class_name);  
  86.             holder.txt_course = (TextView) convertView.findViewById(R.id.txt_pre_entry_course);  
  87.             holder.txt_teacher = (TextView) convertView.findViewById(R.id.txt_pre_entry_teacher);  
  88.   
  89.   
  90.             convertView.setTag(holder);  
  91.         }  
  92.         else  
  93.         {  
  94.             holder = (viewHolder) convertView.getTag();  
  95.         }  
  96.         Log.v("log""-->getView()--ORDER_SUCCESS[" + position + "]-" + ORDER_SUCCESS[position]);  
  97.         // 判断保存的position位置上的Butoon是否已预约成功  
  98.         if (ORDER_SUCCESS[position])  
  99.         {  
  100.             holder.btn_order.setText("已预约");  
  101.             // 这里不设的话返回来时还会可点击,因为向下拉时,Holder里的btn被设置成可点击了  
  102.             // holder.btn_order.setEnabled(false);  
  103.             holder.btn_order.setClickable(false);  
  104.         }  
  105.         else  
  106.         {  
  107.             // 这里要写上默认的显示内容,要不然后面的子控件会出现显示已预订的情况。因为不设置的话btn还是Holder中的btn,而此时holder中的btn是已经设置了已预约的  
  108.             holder.btn_order.setText("未预约");  
  109.             // 要设置为可点击,不然是Holder里的状态  
  110.             // holder.btn_order.setEnabled(true);  
  111.             holder.btn_order.setClickable(true);  
  112.             // 这个也要放这里判断  
  113.             holder.btn_order.setOnClickListener(new btnListener(position, holder.btn_order));  
  114.         }  
  115.         // 课室假数据  
  116.         holder.txt_class.setText(classes[position]);  
  117.         /* 
  118.          * holder.txt_class.setText((CharSequence) 
  119.          * listList.get(position).get(4)); // 
  120.          * holder.txt_class_name.setText(listList.get(position).get()); // 
  121.          * holder.txt_course.setText((CharSequence) 
  122.          * listList.get(position).get(2)); // 
  123.          * holder.txt_teacher.setText((CharSequence) 
  124.          * listList.get(position).get(3)); 
  125.          */  
  126.   
  127.   
  128.         return convertView;  
  129.     }  
  130.   
  131.   
  132.     /** 
  133.      * 要传入当前点击的Button,用于设置currentBtn为当前点击的Button,这样点击后的setText就不会错位了。 
  134.      */  
  135.     class btnListener implements OnClickListener  
  136.     {  
  137.         private int position;  
  138.         private Button Btn;  
  139.   
  140.   
  141.         public btnListener(int position, Button currentBtn)  
  142.         {  
  143.             this.position = position;  
  144.             this.Btn = currentBtn;  
  145.         }  
  146.   
  147.   
  148.         @Override  
  149.         public void onClick(View v)  
  150.         {  
  151.             currentPosition = position;  
  152.             currentBtn = Btn;  
  153.             Toast.makeText(context, "点击第 " + (position + 1) + "个Button"0).show();  
  154.             orderAsyncTask = new OrderAsyncTask();  
  155.             orderAsyncTask.execute("");  
  156.             orderDialog.show();  
  157.         }  
  158.   
  159.   
  160.     }  
  161.   
  162.   
  163.     private static class viewHolder  
  164.     {  
  165.         private Button btn_order;  
  166.         private Button btn_temp;  
  167.         private TextView txt_class, txt_teacher, txt_course, txt_class_name;  
  168.   
  169.   
  170.     }  
  171.   
  172.   
  173.     /** 
  174.      * 异步AsyncTask 
  175.      */  
  176.     private class OrderAsyncTask extends AsyncTask<String, Integer, Integer>  
  177.     {  
  178.   
  179.   
  180.         @Override  
  181.         protected void onPreExecute()  
  182.         {  
  183.             super.onPreExecute();  
  184.         }  
  185.   
  186.   
  187.         // 异步处理  
  188.         @Override  
  189.         protected Integer doInBackground(String... nullNow)  
  190.         {  
  191.             Log.v("log""-->doInBackground()--params-" + nullNow[0]);  
  192.             try  
  193.             {  
  194.                 Thread.sleep(2500);  
  195.                 return SubmitHandler.submitOrder((String) listList.get(currentPosition).get(0), (String) listList  
  196.                                                  .get(currentPosition).get(1), (String) listList.get(currentPosition).get(5),  
  197.                                                  Edu_Survey_OrderInfo.ORDER_WEEK);  
  198.   
  199.   
  200.             }  
  201.             catch (Exception e)  
  202.             {  
  203.                 e.printStackTrace();  
  204.                 Log.v("log""-->doInBackground() ERROR!");  
  205.             }  
  206.             return 0;  
  207.         }  
  208.   
  209.   
  210.         @Override  
  211.         protected void onProgressUpdate(Integer... values)  
  212.         {  
  213.             super.onProgressUpdate(values);  
  214.         }  
  215.   
  216.   
  217.         @Override  
  218.         protected void onPostExecute(Integer responseCode)  
  219.         {  
  220.             Log.v("log""-->responseCode-" + responseCode);  
  221.             //先假设已经请求成功了  
  222.             responseCode = 200;  
  223.             switch (responseCode)  
  224.             {  
  225.             case 200:  
  226.                 ORDER_SUCCESS[currentPosition] = true;  
  227.                 currentBtn.setText("已预约");  
  228.                 // 这里不设的话在当前页面下currentBtn一直可点击,因为getView里设的话是要调用getView时才能起作用的。  
  229.                 // currentBtn.setEnabled(false);  
  230.                 currentBtn.setClickable(false);  
  231.                 break;  
  232.             case 404:  
  233.                 break;  
  234.             default:  
  235.                 break;  
  236.             }  
  237.   
  238.   
  239.             Log.v("log""-->onPostExecute()--currentPosition-" + currentPosition);  
  240.             Log.v("log""-->onPostExecute()--ORDER_SUCCESS[" + currentPosition + "]-"  
  241.                   + ORDER_SUCCESS[currentPosition]);  
  242.             orderDialog.dismiss();  
  243.             super.onPostExecute(responseCode);  
  244.         }  
  245.   
  246.   
  247.     }  
  248.   
  249.   
  250. }  



效果图:




补充:

Button可以设置tag来唯一标记它,之后就可以通过listview.findViewWithTag(tag)找到了。不需要上面这么麻烦。
转自: http://blog.csdn.net/bbld_/article/details/24590345
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值