Jingdong screening updated, very good, very cool. So, we’re not so bad, right? So we have this demo. No more words, first look at the diagram, do not want to see the code of friends, direct point at the bottom of the demo.

In Figure 1, there are only two points. The PopupWindow is half the height of the screen, and the other half is semi-transparent high-end black. If it is simple, it is written with the weight attribute, which is convenient and fast. Then write a GridView in the top half, and a LinearLayout in the bottom of the GridView is used to put two buttons, but it is difficult to handle the layout of the buttons. In line with the principle of high imitation, I still use the TextView. Ha ha, smart as me. The layout is simple, but I didn’t have to think too hard to figure it out. Let’s look at the core code for PopupWindow: the ##### pricepopup.java variable

    private View contentView;
    private GridView grid;
    private TextView reset;
    private TextView ok;
    private PopupAdapter adapter;
    private List<Vo> data;
Copy the code

The main method

    public PricePopup(final Activity context, final List<Vo> data) {
        this.data = data;
        adapter = new PopupAdapter(context);
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        contentView = inflater.inflate(R.layout.popup, null);
        grid = (GridView) contentView.findViewById(R.id.grid);
        reset = (TextView) contentView.findViewById(R.id.reset);
        ok = (TextView) contentView.findViewById(R.id.ok);
        grid.setAdapter(adapter);
        grid.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<? > adapterView, View view, int position, long l) { data.get(position).setChecked(! data.get(position).isChecked());for (int i = 0; i < data.size(); i++) {
                    if (i == position) {
                        continue;
                    }
                    data.get(i).setChecked(false); } Toast.makeText(context, data.get(position).getStr2(), Toast.LENGTH_SHORT).show(); adapter.notifyDataSetChanged(data); }}); int h = context.getWindowManager().getDefaultDisplay().getHeight(); int w = context.getWindowManager().getDefaultDisplay().getWidth(); this.setContentView(contentView); this.setWidth(w); this.setHeight(h); ColorDrawable dw = new ColorDrawable(00000000); this.setBackgroundDrawable(dw); this.setFocusable(true);
        this.setOutsideTouchable(false);
        this.update();
    }
Copy the code

Show the popupWindow method

    public void showPricePopup(View parent, final List<Vo> data) {
        if(! this.isShowing()) { this.showAsDropDown(parent); adapter.notifyDataSetChanged(data); }else{ this.dismiss(); }}Copy the code

Grey transparent background on the left

    <View
        android:id="@+id/popup_goods_noview"
        android:layout_width="48dp"
        android:layout_height="match_parent"
        android:background="# 88000000" />
Copy the code

Since the layout is horizontal and linear, the width of the layout on the right is match_parent.

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#ffffff"< div style = "box-sizing: border-box; word-wrap: break-word! Important;"match_parent"
                android:layout_height="match_parent">

                <ListView
                    android:id="@+id/selection_list"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:divider="@null"
                    android:dividerHeight="14dp"
                    android:orientation="vertical"
                    android:scrollbars="none"/> </RelativeLayout> // Bottom reset and OK buttons <LinearLayout Android :id="@+id/filter_layout"
            android:layout_width="match_parent"
            android:layout_height="48dp"
            android:layout_alignParentBottom="true"
            android:background="#ffffff"
            android:orientation="vertical"<View android:layout_width="match_parent"
                android:layout_height="1px"
                android:background="#cccccc" />

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="48dp"
                android:gravity="center_vertical"
                android:orientation="horizontal">

                <TextView
                    android:id="@+id/filter_reset"
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:gravity="center"
                    android:text="Reset" />

                <TextView
                    android:id="@+id/filter_sure"
                    android:layout_width="0dp"
                    android:layout_height="match_parent"
                    android:layout_weight="1"
                    android:background="#ff0033"
                    android:gravity="center"
                    android:text="Sure"
                    android:textColor="#ffffff" />
            </LinearLayout>
        </LinearLayout>
    </RelativeLayout>
Copy the code

PopupWindow code:

// private View contentView; private Context context; private View goodsNoView; private GridView serviceGrid; private ListView selectionList; private TextView filterReset; private TextView filterSure; private GoodsAttrListAdapter adapter; private GoodsAttrsAdapter serviceAdapter; private List<SaleAttributeNameVo> itemData; private List<SaleAttributeVo> serviceList; private String[] serviceStr = new String[]{"Only if it's available."."Promotion"."Mobile Exclusive"};
Copy the code

The main method

    public FilterPopupWindow(final Activity context) {
        this.context = context;
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        contentView = inflater.inflate(R.layout.popup_goods_details, null);
        goodsNoView = contentView.findViewById(R.id.popup_goods_noview);
        serviceGrid = (GridView) contentView.findViewById(R.id.yuguo_service);
        selectionList = (ListView) contentView.findViewById(R.id.selection_list);
        filterReset = (TextView) contentView.findViewById(R.id.filter_reset);
        filterSure = (TextView) contentView.findViewById(R.id.filter_sure);

        goodsNoView.setOnClickListener(new CancelOnClickListener());
        contentView.setOnKeyListener(new OnKeyListener() {
            @Override
            public boolean onKey(View v, int keyCode, KeyEvent event) {
                if (event.getAction() == KeyEvent.ACTION_DOWN && keyCode == KeyEvent.KEYCODE_BACK) {
                    dismiss();
                }
                return true; }}); serviceList = new ArrayList<SaleAttributeVo>();for (int i = 0; i < serviceStr.length; i++) {
            SaleAttributeVo vo = new SaleAttributeVo();
            vo.setValue(serviceStr[i]);
            serviceList.add(vo);
        }
        serviceAdapter = new GoodsAttrsAdapter(context);
        serviceGrid.setAdapter(serviceAdapter);
        serviceAdapter.notifyDataSetChanged(true, serviceList);
Copy the code

The gridview listening

        serviceGrid.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<? > arg0, View arg1, int arg2, long arg3) {// Set the status of the currently selected position to not. serviceList.get(arg2).setChecked(! serviceList.get(arg2).isChecked());for(int i = 0; i < serviceList.size(); I++) {// skip the state of the selected position that has been setif (i == arg2) {
                        continue;
                    }
                    serviceList.get(i).setChecked(false);
                }
                serviceAdapter.notifyDataSetChanged(true, serviceList); }});Copy the code

data

itemData = new ArrayList<SaleAttributeNameVo>(); adapter = new GoodsAttrListAdapter(context, itemData); selectionList.setAdapter(adapter); // To make it easier to look at the code, there is only one data String STR ="["
                + "{\"nameId\":\"V2QASD\",\"saleVo\":["
                + "{\" value \ ": \" 2 nuclear \ ", \ "goods \" : null, \ "goodsAndValId \" : \ "C6VOWQ \", \ "checkStatus \" : \ "1 \}","
                + "{\" value \ ": \" 4 nuclear \ ", \ "goods \" : null, \ "goodsAndValId \" : \ "C6VOWQ \", \ "checkStatus \" : \ \ "0"},"
                + "{\" value \ ": \" six nuclear \ ", \ "goods \" : null, \ "goodsAndValId \" : \ "C6VOWQ \", \ "checkStatus \" : \ \ "0"},"
                + "{\" value \ ": \" eight nuclear \ ", \ "goods \" : null, \ "goodsAndValId \" : \ "C6VOWQ \", \ "checkStatus \" : \ \ "0"}"
                + "],\"name\":\"CPU\"}";
        JSONArray json = null;
        try {
            json = new JSONArray(str);
            refreshAttrs(json);
        } catch (JSONException e) {
            e.printStackTrace();
        }
Copy the code

Reset click-listening with all options set to false

        filterReset.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                for (int i = 0; i < itemData.size(); i++) {
                    for (int j = 0; j < itemData.get(i).getSaleVo().size(); j++) {
                        itemData.get(i).getSaleVo().get(j).setChecked(false); } } adapter.notifyDataSetChanged(); }});Copy the code

Click ok to listen and list all selected items

        filterSure.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                String str = "";
                for (int i = 0; i < itemData.size(); i++) {
                    for (int j = 0; j < itemData.get(i).getSaleVo().size(); j++) {
                        if(itemData.get(i).getSaleVo().get(j).isChecked()) { str = str + itemData.get(i).getSaleVo().get(j).getValue(); } } } Toast.makeText(FilterPopupWindow.this.context, str, Toast.LENGTH_SHORT).show(); }});Copy the code

Set the popupWindow property

        this.setContentView(contentView);
        this.setWidth(LayoutParams.MATCH_PARENT);
        this.setHeight(LayoutParams.MATCH_PARENT);
        ColorDrawable dw = new ColorDrawable(00000000);
        this.setBackgroundDrawable(dw);
        this.setFocusable(true);
        this.setOutsideTouchable(false);
        this.update();

    }
Copy the code

Refresh commodity Attributes

    public void refreshAttrs(JSONArray json) throws JSONException {
        itemData.clear();
        for (int i = 0; i < json.length(); i++) {
            SaleAttributeNameVo saleName = new SaleAttributeNameVo();
            JSONObject obj = (JSONObject) json.opt(i);
            saleName.setName(obj.getString("name"));
            List<SaleAttributeVo> list = new ArrayList<SaleAttributeVo>();
            net.sf.json.JSONArray array = new net.sf.json.JSONArray();
            array = net.sf.json.JSONArray.fromObject(obj.getString("saleVo"));
            for (int j = 0; j < array.size(); j++) {
                net.sf.json.JSONObject object = array.getJSONObject(j);
                SaleAttributeVo vo = new SaleAttributeVo();
                vo.setGoods(object.getString("goods"));
                vo.setValue(object.getString("value"));
                vo.setGoodsAndValId(object.getString("goodsAndValId"));
                if ("1".equals(object.getString("checkStatus"))) {
                    vo.setChecked(true);
                } else {
                    vo.setChecked(false); } list.add(vo); } saleName.setSaleVo(list); / / whether saleName. SetNameIsChecked (false);
            itemData.add(saleName);
        }
        adapter.notifyDataSetChanged();
    }
Copy the code

Handles the disappearance of popupWindow

    public class CancelOnClickListener implements OnClickListener {
        @Override
        public void onClick(View v) {
            dismiss();
        }
    }

    public boolean onKeyDown(Context context, int keyCode, KeyEvent event) {
        this.context = context;
        if (event.getAction() == KeyEvent.ACTION_DOWN && keyCode == KeyEvent.KEYCODE_BACK) {
            dismiss();
        }
        return true;
    }
Copy the code

According to popupwindow

    public void showFilterPopup(View parent) {
        if(! this.isShowing()) { this.showAsDropDown(parent); }else{ this.dismiss(); }}Copy the code

Well, it seems that the code is a little long. I can’t help it. There are so many things. This one is optional:

The #### property is the adapter variable for listView

    private Context context;
    private List<SaleAttributeNameVo> data;
Copy the code

The main method

    public GoodsAttrListAdapter(Context context, List<SaleAttributeNameVo> data) {
        this.context = context;
        this.data = data;
    }
Copy the code

The key to the

    @Override
    public View getView(final int position, View v, ViewGroup parent) {
        final MyView myView;
        if (v == null) {
            myView = new MyView();
            v = View.inflate(context, R.layout.item_goods_attr_list, null);
            myView.name = (TextView) v.findViewById(R.id.attr_list_name);
            myView.img = (ImageView) v.findViewById(R.id.attr_list_img);
            myView.grid = (GridView) v.findViewById(R.id.attr_list_grid);
            myView.grid.setSelector(new ColorDrawable(Color.TRANSPARENT));
            v.setTag(myView);
        } else {
            myView = (MyView) v.getTag();
        }
        myView.name.setText(data.get(position).getName());
        final GoodsAttrsAdapter adapter = new GoodsAttrsAdapter(context);
        myView.grid.setAdapter(adapter);
        adapter.notifyDataSetChanged(data.get(position).isNameIsChecked(), data.get(position).getSaleVo());
Copy the code

Expand to hide more properties

        myView.img.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                if (data.get(position).isNameIsChecked()) {
                    ((ImageView) v).setImageResource(R.drawable.sort_common_up);
                } else {
                    ((ImageView) v).setImageResource(R.drawable.sort_common_down);
                }
                adapter.notifyDataSetChanged(data.get(position).isNameIsChecked(), data.get(position).getSaleVo());
                data.get(position).setNameIsChecked(!data.get(position).isNameIsChecked());
            }
        });
Copy the code

Item selection event

        myView.grid.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<? > arg0, View arg1, int arg2, long arg3) {// Set the status of the currently selected position to not. data.get(position).getSaleVo().get(arg2).setChecked(! data.get(position).getSaleVo().get(arg2).isChecked());for(int i = 0; i < data.get(position).getSaleVo().size(); I++) {// skip the state of the selected position that has been setif (i == arg2) {
                        continue;
                    }
                    data.get(position).getSaleVo().get(i).setChecked(false);
                }
                if(! data.get(position).isNameIsChecked()) { myView.img.setImageResource(R.drawable.sort_common_up); }else {
                    myView.img.setImageResource(R.drawable.sort_common_down);
                }
                adapter.notifyDataSetChanged(!data.get(position).isNameIsChecked(), data.get(position).getSaleVo());
            }
        });
        return v;
    }
Copy the code

You know that

    static class MyView {
        public TextView name;
        public ImageView img;
        public GridView grid;
    }
Copy the code

This is multiple-choice, only myView. The grid. The setOnItemClickListener () method is different, the radio the other selected is set to false, don’t have to code inside pass, need friends here. :

        myView.grid.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<? > arg0, View arg1, int arg2, long arg3) {// Set the status of the currently selected position to not. data.get(position).getSaleVo().get(arg2).setChecked(!data.get(position).getSaleVo().get(arg2).isChecked());
                adapter.notifyDataSetChanged(data.get(position).isNameIsChecked(), 
	                data.get(position).getSaleVo());
            }
        });
        return v;
    }
Copy the code

Let me put the monitor in here. The internal Adapter is getView

    @Override
    public View getView(final int position, View v, ViewGroup parent) {
        final MyView myView;
        if (v == null) {
            myView = new MyView();
            v = View.inflate(context, R.layout.item_goods_attrs, null);
            myView.attr = (TextView) v.findViewById(R.id.attr_name);
            v.setTag(myView);
        } else{ myView = (MyView) v.getTag(); } myView.attr.setText(data.get(position).getValue()); /** * Sets the background and font color of the item based on the selected state */if (data.get(position).isChecked()) {
            myView.attr.setBackgroundResource(R.drawable.goods_attr_selected_shape);
            myView.attr.setTextColor(Color.WHITE);
        } else {
            myView.attr.setBackgroundResource(R.drawable.goods_attr_unselected_shape);
            myView.attr.setTextColor(Color.GRAY);
        }
        return v;
    }
Copy the code

You know that

    static class MyView {
        public TextView attr;
    }
Copy the code

Autotype notifyDataSetChanged ()

    @Override
    public void notifyDataSetChanged() {
        super.notifyDataSetChanged();
    }

    public void notifyDataSetChanged(boolean isUnfold,
                                     final List<SaleAttributeVo> tempData) {
        if (tempData == null || 0 == tempData.size()) {
            return; } data.clear(); // If it is expanded, add all data, otherwise display only 3 dataif (isUnfold) {
            data.addAll(tempData);
        } else {
            data.add(tempData.get(0));
            data.add(tempData.get(1));
            data.add(tempData.get(2));
        }
        notifyDataSetChanged();
    }
Copy the code

So isNameIsChecked() is actually lazy and didn’t change the name, and that’s what you need to expand the child property.

Ok, sauce. The demo release: http://download.csdn.net/detail/u013806766/9579156


I used Eclipse to write this file first. I used Android Studio to select Gradle, and then used Android Studio to edit this file.

Gradle failed to compile. The project name \gradle\wrapper\gradle-wrapper distributionUrl=http\://services.gradle.org/distributions/gradle-1.12-all.zip instead Following distributionUrl=http\://services.gradle.org/distributions/gradle-2.10-all.zip gradle version in the development environment configurationCopy the code

This article was reedited on May 25, 2017. It will not have used Markdown of Jane Books before, and there was no time to learn. Recently to understand again, so, the code complete, also try to write the comments clear, convenient for everyone to read. If you have any questions, please leave a message.