ListView嵌套两个EditText相关显示问题

这里说明:本人第一次写博客,可能写的不算太好。但是这个相关类型的研究与拓展,是项目中比较难得的,所以开一篇博客来总结和思考,先让我们看看项目需求。

项目需求在这

项目需求说明:
1、需要在点击EditText的时候显示Button
2、点击其他条目的EditText的时候,必须在当前条目中显示Button,其他条目中的Button必须隐藏
3、滚动ListView的时候不能够显示错乱信息和错乱显示
4、在滚动的时候,如果条目不显示,那么必须隐藏Button

Content:
注意:布局文件就不需要仔细去看了,主要还是根据需求来写对应的代码,完成功能就好。
/**我们就看这个适配器里面的内容,在listView显示和ListView适配的时候,适配器始终是一个重要的相关内容,我们把适配器提取出来,仔细研究到底是怎么做到适配的。*/
public class ProductManagerAdapter extends BaseAdapter {
    private List<Products> products;//数据源
    private Context context;//上下文
    private Handler handler;//主线程载体
    //private static int temp = -1;//控件静态id来保持单一性
    private static ViewHolder tempHolder = null;//控件静态重用对象,用来保持单一性
    public ProductManagerAdapter(List<Products> products, Context context,
            String type, Handler handler) {//构造方法,传递外界数据以及对应的上下文信息
        super();
        this.products = products;
        this.context = context;
        this.handler = handler;
    }

    public void updataAdapter(List<Products> products) {//公开方法,用来动态改变显示条目
        if (products != null) {
            this.products = products;
            notifyDataSetChanged();
        }
    }

    @Override
    public int getCount() {

        return products == null ? 0 : products.size();
    }

    @Override
    public Object getItem(int position) {

        return products.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }
    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
        final Products product = products.get(position);
        ViewHolder holder = null;

        if (convertView == null) {
            holder = new ViewHolder();
            convertView = View.inflate(context, R.layout.item_products_manager,
                    null);
            holder.price_save = (TextView) convertView
                    .findViewById(R.id.price_save);
            holder.product_chengben = (EditText) convertView
                    .findViewById(R.id.product_chengben);
            holder.product_price = (EditText) convertView
                    .findViewById(R.id.product_price);
            holder.product_chengben.setTag(position); //保存对应的条目位置,防止被重用
            holder.product_price.setTag(position); //保存对应的条目位置,防止被重用
            **savingPosition**(holder, holder.product_chengben, "chengben", position);//重要方法A~参见后面详细分析
            **savingPosition**(holder, holder.product_price, "price", position);
            convertView.setTag(holder);
            holder.price_save.setVisibility(View.GONE);//条目创建的时候为了摆脱焦点控制机制,所以使用强制性质要求不能够显示button
        } else {
            holder = (ViewHolder) convertView.getTag();
            loseFoucus(holder);//失去焦点
            holder.product_price.setTag(position);
            holder.product_chengben.setTag(position);
            holder.price_save.setVisibility(View.GONE);//滑动过程中,让显示的条目消失
        }

        return convertView;
    }
    class ViewHolder {
        /** 商品价格 */
        EditText product_price;
        /** 商品成本 */
        EditText product_chengben;
        /** 保存按钮 */
        TextView price_save;
    }

在这之前的代码是完整的实现listView显示的控制代码,里面分别的集中几种方法很重要,必须单独拧出来谈。
以下是重要方法A:savingPosition,下面我们详细分析。

    /** edittext公共操作 
     * @param position **/
    private void savingPosition(ViewHolder holder, final EditText ev,
            final String type, int position) {

        ev.addTextChangedListener(new ThisWatcher(holder) {//为EditText做监听

            @Override
            public void afterTextChanged(Editable s, ViewHolder holder) {
                int p = (Integer) ev.getTag();//获取对应的position
                savaData(p, s.toString(), type, holder);//重要方法B~参见后面详细分析
            }

        });
        ev.setOnFocusChangeListener(new ForcusChangeDate(holder));//重要监听~参见后面详细分析

    }

重要方法B:在保存对应的EditText信息中,使得EditText的内容能够保持在本地缓存中,不被因为页面转换而被消失改变


    private void savaData(int p, String s, String tag, ViewHolder holder) {
        if (p > products.size()) {//控制焦点
            if ("chengben".equals(tag)) {
                holder.product_chengben.clearFocus();
            } else if ("price".equals(tag)) {
                holder.product_price.clearFocus();
            }

            return;
        } else {
            Products product = products.get(p);
            if ("chengben".equals(tag)) {
                product.setCostprice(s);
            } else if ("price".equals(tag)) {
                product.setSaleprice(s);
            }

            products.set(p, product);
        }

    }


    private abstract class ThisWatcher implements TextWatcher {
        ViewHolder holder;

        public ThisWatcher(ViewHolder holder) {
            super();
            this.holder = holder;
        }

        @Override
        public void afterTextChanged(Editable s) {
            afterTextChanged(s, holder);
        }

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count,
                int after) {

        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before,
                int count) {


        }

        public abstract void afterTextChanged(Editable s, ViewHolder holder);

    }

重要监听:这里是最为困难的地方,在写这段代码的时候,遇到很多困难,正是因为这些困难,我保留了一些遇到的问题代码,来详细讲解。

    private class ForcusChangeDate implements OnFocusChangeListener  {

        ViewHolder holder;

        public ForcusChangeDate(ViewHolder holder) {
            super();
            this.holder = holder;
        }

        /**这里出现了比较多的问题,需要详细的去注意细节控制button的显示*/
        @Override
        public void onFocusChange(View v, boolean hasFocus) {
            /**A:这是正确的方法,将holoder控制成静态方法,然后根据每个条目的不同来进行*/
            if(hasFocus)
            {
                if(tempHolder == null)
                {
                    //temp = v.getId();
                    tempHolder = holder;
                    holder.price_save.setVisibility(View.VISIBLE);
                }
                else if(tempHolder == holder)
                {
                    holder.price_save.setVisibility(View.VISIBLE);

                }
                else if(tempHolder != holder)
                {
                    tempHolder.price_save.setVisibility(View.GONE);
                    tempHolder=holder;
                    holder.price_save.setVisibility(View.VISIBLE);
                }
            }




    /**B:这是其中的一种思路,将每个EditText的ID来控制下来,重用显示,但是由于有两个EditText存在,所以此方法不合适*/

//          if (hasFocus) {
//                  if (temp == -1) {
//                      holder.price_save.setVisibility(View.VISIBLE);
//                      if (v.getId() == holder.product_chengben.getId()) {
//                          temp = holder.product_chengben.getId();
//                      }else if (v.getId() == holder.product_price.getId()) {
//                          temp = holder.product_price.getId();
//                      }
//                  }else if (temp == holder.product_chengben.getId()|| temp == holder.product_price.getId()) {
//                      holder.price_save.setVisibility(View.VISIBLE);
//                  }
//                  
//                  
//              
//          }

    /**C: 这是刚刚开始的方法,将两种进行判断,但是在实践的过程中发现Android5.0以下的机制可以实现。
    Android5.0以上,将focus机制产生了变化。
    使得此监听器一直处于运转状态,故一直在true和false中进行无限判断循环
    所以不适用
*/  

            /*if (hasFocus) {
                holder.price_save.setVisibility(View.VISIBLE);  
            } else {
                holder.price_save.setVisibility(View.GONE);
            }*/


        }

    }



/**让EditText失去焦点*/
    private void loseFoucus(ViewHolder holder) {
        holder.product_chengben.clearFocus();
        holder.product_price.clearFocus();
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值