热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

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

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

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

 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的布局



android:layout_
android:layout_
android:descendantFocusability="blocksDescendants"
android:orientation="horizontal" >

android:layout_
android:layout_
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical" >

android:id="@+id/txt_pre_entry_class"
android:layout_
android:layout_
android:singleLine="true"
android:text="test" />


android:layout_
android:layout_
android:layout_weight="2"
android:gravity="center"
android:orientation="vertical" >

android:id="@+id/txt_pre_entry_teacher"
android:layout_
android:layout_
android:singleLine="true"
android:text="Txt1" />

android:id="@+id/txt_pre_entry_course"
android:layout_
android:layout_
android:singleLine="true"
android:text="Txt2" />

android:id="@+id/txt_pre_entry_class_name"
android:layout_
android:layout_
android:singleLine="true"
android:text="Txt3" />


android:layout_
android:layout_
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical" >

android:id="@+id/btn_pre_entry_order"
android:layout_
android:layout_
android:singleLine="true"
android:background="@drawable/button_rounded"
android:text="未预约"
/>





ListView的Adapter

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 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 listSize, 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
    {


        @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)找到了。不需要上面这么麻烦。




推荐阅读
  • RecyclerView初步学习(一)
    RecyclerView初步学习(一)ReCyclerView提供了一种插件式的编程模式,除了提供ViewHolder缓存模式,还可以自定义动画,分割符,布局样式,相比于传统的ListVi ... [详细]
  • dotnet 通过 Elmish.WPF 使用 F# 编写 WPF 应用
    本文来安利大家一个有趣而且强大的库,通过F#和C#混合编程编写WPF应用,可以在WPF中使用到F#强大的数据处理能力在GitHub上完全开源Elmis ... [详细]
  • 本文介绍如何在 Android 中通过代码模拟用户的点击和滑动操作,包括参数说明、事件生成及处理逻辑。详细解析了视图(View)对象、坐标偏移量以及不同类型的滑动方式。 ... [详细]
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • Explore how Matterverse is redefining the metaverse experience, creating immersive and meaningful virtual environments that foster genuine connections and economic opportunities. ... [详细]
  • 本文详细介绍了如何解决Uploadify插件在Internet Explorer(IE)9和10版本中遇到的点击失效及JQuery运行时错误问题。通过修改相关JavaScript代码,确保上传功能在不同浏览器环境中的一致性和稳定性。 ... [详细]
  • 导航栏样式练习:项目实例解析
    本文详细介绍了如何创建一个具有动态效果的导航栏,包括HTML、CSS和JavaScript代码的实现,并附有详细的说明和效果图。 ... [详细]
  • IneedtofocusTextCellsonebyoneviaabuttonclick.ItriedlistView.ScrollTo.我需要通过点击按钮逐个关注Tex ... [详细]
  • 使用 Azure Service Principal 和 Microsoft Graph API 获取 AAD 用户列表
    本文介绍了一段通用代码示例,该代码不仅能够操作 Azure Active Directory (AAD),还可以通过 Azure Service Principal 的授权访问和管理 Azure 订阅资源。Azure 的架构可以分为两个层级:AAD 和 Subscription。 ... [详细]
  • 将Web服务部署到Tomcat
    本文介绍了如何在JDeveloper 12c中创建一个Java项目,并将其打包为Web服务,然后部署到Tomcat服务器。内容涵盖从项目创建、编写Web服务代码、配置相关XML文件到最终的本地部署和验证。 ... [详细]
  • 在使用 DataGridView 时,如果在当前单元格中输入内容但光标未移开,点击保存按钮后,输入的内容可能无法保存。只有当光标离开单元格后,才能成功保存数据。本文将探讨如何通过调用 DataGridView 的内置方法解决此问题。 ... [详细]
  • 基于KVM的SRIOV直通配置及性能测试
    SRIOV介绍、VF直通配置,以及包转发率性能测试小慢哥的原创文章,欢迎转载目录?1.SRIOV介绍?2.环境说明?3.开启SRIOV?4.生成VF?5.VF ... [详细]
  • 深入了解 Windows 窗体中的 SplitContainer 控件
    SplitContainer 控件是 Windows 窗体中的一种复合控件,由两个可调整大小的面板和一个可移动的拆分条组成。本文将详细介绍其功能、属性以及如何通过编程方式创建复杂的用户界面。 ... [详细]
  • 2023年京东Android面试真题解析与经验分享
    本文由一位拥有6年Android开发经验的工程师撰写,详细解析了京东面试中常见的技术问题。涵盖引用传递、Handler机制、ListView优化、多线程控制及ANR处理等核心知识点。 ... [详细]
  • 从 .NET 转 Java 的自学之路:IO 流基础篇
    本文详细介绍了 Java 中的 IO 流,包括字节流和字符流的基本概念及其操作方式。探讨了如何处理不同类型的文件数据,并结合编码机制确保字符数据的正确读写。同时,文中还涵盖了装饰设计模式的应用,以及多种常见的 IO 操作实例。 ... [详细]
author-avatar
骑猪猪-逛恋空
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有