这两天用到了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