Android listview中item的點擊顯示或隱藏錯亂的解決辦法

在listview的adapter中作item點擊監聽事件時會出現顯示錯亂的問題,這個問題的解決辦法也就是爲點擊的控件加一個tag,以下代碼:數組

public class PriceMenuDetailAdapter extends BaseAdapter {

    private ArrayList<AddQuotationBean.ASQuotations> list_quotation;
    private Context context;
    private boolean[] showControl;//代表對應的item是否須要展開

    public PriceMenuDetailAdapter(ArrayList<AddQuotationBean.ASQuotations> list_quotation, Context context) {
        this.list_quotation = list_quotation;
        this.context = context;
        showControl = new boolean[list_quotation.size()];//此時數組中的默認值都是false
    }

    @Override
    public View getView(int i, View view, ViewGroup viewGroup) {
        ViewHolder viewHolder = null;
        if (view == null) {
            view = LayoutInflater.from(context).inflate(R.layout.item_price_menu_detail, null);
            viewHolder = new ViewHolder();
           /*加載id*/
            view.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) view.getTag();
        }
        AddQuotationBean.ASQuotations asQuotations = list_quotation.get(i);
        viewHolder.tv_space_name.setText(asQuotations.SpaceName);
        viewHolder.tv_diff_sum.setText("¥" + Util.getNonScientificCount(asQuotations.SpaceTotalMoney + "", true));
        viewHolder.ll_info.removeAllViews();
        ArrayList<AddQuotationBean.QDetails> list_detail = asQuotations.QDetails;
        for (int k = 0; k < list_detail.size(); k++) {
            viewHolder.ll_info.addView(returnView(list_detail.get(k), k, list_detail.size()));
        }

        viewHolder.price_detail_layout.setTag(i);//爲點擊的區域設置Tag爲position
        if (showControl[i]) {//加載item的時候查看是否須要打開或隱藏
            viewHolder.ll_info.setVisibility(View.GONE);
        } else {
            viewHolder.ll_info.setVisibility(View.VISIBLE);
        }
        viewHolder.price_detail_layout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int tag = (int) v.getTag();//獲取點擊位置對應的tag值
                if (showControl[tag]) {//改變數組中對應的值
                    showControl[tag] = false;
                } else {
                    showControl[tag] = true;
                }
               ** notifyDataSetChanged();//從新加載**
            }
        });

        return view;
    }

    private class ViewHolder{
        private TextView tv_space_name;// 空間名
        private TextView tv_diff_sum;// 差價小計
        private LinearLayout ll_info;// 材料信息
        private RelativeLayout price_detail_layout;//空間名和差價小計總體的佈局
    }

}

注意:咱們平時對 ListView 作的最多的操做就是 setOnItemClickListener,這個操做通常都是在 Activity 中進行的,此時響應區域是 Item 總體,無論你點擊 Item 的哪一個角落都會響應。而對於每一個 Item 中子控件的事件監聽(區別於整個Item,好比說 Item 中的按鈕、輸入框等等)都是在適配器類中添加,此時只有點擊添加監聽的子控件區域纔會響應,至關於每一個 Item 中的該控件都添加了監聽。OnClick 的響應優先級:子控件(元控件)> 父佈局(可是不像 onTouch 事件有 Boolean 返回值那樣,OnClick 事件是沒有返回值的,便是「阻斷式式響應」,不會再響應它所歸屬的上層控件)。ide

能夠看到上面代碼中加粗的" notifyDataSetChanged();//從新加載"這一句,這樣寫在adapter裏面,若是是數據量大的狀況下會形成listview滑動出現卡頓的現象,爲了不出現這種狀況,能夠修改代碼以下:佈局

/**@title PriceMenuDetailAdapter 填寫報價單詳情頁面ListView的適配器
 * @author Eric
 * @date 2017/3/30
 **/
public class PriceMenuDetailAdapter extends BaseAdapter {

    private ArrayList<AddQuotationBean.ASQuotations> list_quotation;
    private Context context;
    private boolean[] isShowContentClose;//代表對應的item是否須要展開,true爲隱藏,false爲打開

    public PriceMenuDetailAdapter(ArrayList<AddQuotationBean.ASQuotations> list_quotation, Context context) {
        this.list_quotation = list_quotation;
        this.context = context;
        isShowContentClose = new boolean[list_quotation.size()];//此時數組中的默認值都是false
    }
    @Override
    public View getView(int i, View view, ViewGroup viewGroup) {
        ViewHolder viewHolder = null;
        if (view == null) {
            view = LayoutInflater.from(context).inflate(R.layout.item_price_menu_detail, null);
            viewHolder = new ViewHolder();
           /*加載id*/
            view.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) view.getTag();
        }
        AddQuotationBean.ASQuotations asQuotations = list_quotation.get(i);
        viewHolder.tv_space_name.setText(asQuotations.SpaceName);
        viewHolder.tv_diff_sum.setText("¥" + Util.getNonScientificCount(asQuotations.SpaceTotalMoney + "", true));

        viewHolder.ll_info.removeAllViews();
        ArrayList<AddQuotationBean.QDetails> list_detail = asQuotations.QDetails;
        for (int k = 0; k < list_detail.size(); k++) {
            viewHolder.ll_info.addView(returnView(list_detail.get(k), k, list_detail.size()));
        }

        viewHolder.price_detail_layout.setTag(i);//爲點擊的區域設置Tag爲position
         //至關於初始化控件的顯示或隱藏
        if (isShowContentClose[i]) {//加載item的時候查看是否須要打開或隱藏
            viewHolder.ll_info.setVisibility(View.GONE);
        } else {
            viewHolder.ll_info.setVisibility(View.VISIBLE);
        }
        actionClick(viewHolder.price_detail_layout, viewHolder.ll_info);


        return view;
    }

    //點擊事件監聽
    private void actionClick(final RelativeLayout price_detail_layout, final LinearLayout ll_info) {
        try {
            price_detail_layout.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    int tag = (int) v.getTag();//獲取點擊位置對應的tag值
                    if (isShowContentClose[tag]) {//改變數組中對應的值
                        isShowContentClose[tag] = false;
                    } else {
                        isShowContentClose[tag] = true;
                    }
                    if (isShowContentClose[tag]) {//加載item的時候查看是否須要打開或隱藏
                        //手風琴效果,若是爲true則隱藏若是爲false則打開
                        ll_info.setVisibility(View.GONE);
                    } else {
                        ll_info.setVisibility(View.VISIBLE);
                    }
                }
            });
        } catch (Exception e) {
            LogUtil.e(getClass(), "actionClick()", e);
        }
    }

    private class ViewHolder{
        private TextView tv_space_name;// 空間名
        private TextView tv_diff_sum;// 差價小計
        private LinearLayout ll_info;// 材料信息
        private RelativeLayout price_detail_layout;//空間名和差價小計總體的佈局
    }
}

總結:用一個集合加載position對應控件的tag狀態,先初始化控件的隱藏或顯示,在點擊事件裏面,改變對應集合的狀態,而後改變控件的隱藏或顯示.this

相關文章
相關標籤/搜索