Android custom hierarchical Filtering Control

Source: Internet
Author: User

Android custom hierarchical Filtering Control

This afternoon I wrote a hierarchical filtering control. The effect is as follows:

The control consists of two parts:
1. The filter title button in the above row (four togglebuttons, dynamically appended based on the number of filtering items)
2. Click the filter content (A Popupwindow that contains a Gridview and a Button)

Requirement Development point:
1. Generate the content view of a single filter item, that is, the content of the Popupwindow.
2. Implement the main control, add the content in the above row (four filtering items here) based on the quantity of filtering items, and associate each filtering item.

1. Generate a single pop-up content View
A single view refers to the section in the red box below.

First, what does a single view contain?
1) A Gridview
2) A bottom Button
3) The List of filtered data <\ string> refers to schools A and B.
4) In fact, the title above (university, department, etc.) also comes down to a part of a single pop-up view, so there must also be a variable called title

Conclusion: the generation of a single view contains at least four member variables. Therefore, the implementation of a single view is as follows:

Package com. example. expandableview; import java. util. arrayList; import java. util. list; import com. example. expandableview. adapter. myBaseAdapter; import com. example. expandableview. adapter. viewHolder; import android. content. context; import android. util. attributeSet; import android. view. layoutInflater; import android. view. view; import android. widget. adapterView; import android. widget. adapterView. onItemClickListener; import android. widget. button; import android. widget. gridView; import android. widget. linearLayout; public class ExpandleItemView extends LinearLayout {/** the title text displayed in toggleButton */public String mTitle;/** the bottom Button */private Button mBottomBtn; /** display the data to be filtered */private GridView mGridView;/** filtered data content */private List
  
   
MGridviewDatas; public ExpandleItemView (Context context, AttributeSet attrs, int defStyleAttr) {super (context, attrs, expiration);} public ExpandleItemView (Context context, AttributeSet attrs) {this (context, attrs,-1);} public ExpandleItemView (Context context) {this (context, null);} public ExpandleItemView (String title, Context context, List
   
    
Datas) {this (context); setTitle (title); mGridviewDatas = datas; init ();} private void init () {setBackgroundColor (getResources (). getColor (android. r. color. white);/** Add the layout inflate to this view */LayoutInflater. from (getContext ()). inflate (R. layout. expand_item_layout, this, true); setOrientation (LinearLayout. VERTICAL); mGridView = (GridView) findViewById (R. id. gridview); mBottomBtn = (Button) findViewById (R. id. btn_all);/** use a self-written universal adapter to input data items and layoutid. */mGridView is used in one sentence. setAdapter (new MyBaseAdapter
    
     
(MGridviewDatas, R. layout. gridview_item, getContext () {@ Override protected void convert (ViewHolder viewHolder, String t) {viewHolder. setBtnText (R. id. item_text, t) ;}});/** calls back each subitem to the listener */mGridView. setOnItemClickListener (new OnItemClickListener () {@ Override public void onItemClick (AdapterView
     Parent, View view, int position, long id) {if (mOnExpandItemClick! = Null) {mOnExpandItemClick. onItemClick (position) ;}});/** Click Event at the bottom of the button to callback to the listener */mBottomBtn. setOnClickListener (new OnClickListener () {@ Override public void onClick (View v) {if (mOnExpandItemClick! = Null) {mOnExpandItemClick. onBottomClick () ;}});} public String getTitle () {return mTitle = null? New String (): mTitle;} public void setTitle (String mTitle) {this. mTitle = mTitle;} public List
     
      
GetmGridviewDatas () {return mGridviewDatas = null? New ArrayList
      
        (): MGridviewDatas;} public void setmGridviewDatas (List
       
         MGridviewDatas) {this. mGridviewDatas = mGridviewDatas;}/*** the height of the accumulate subclass is used as its own height */@ Override protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec) {int cCount = getChildCount (); int desireWidth = MeasureSpec. getSize (widthMeasureSpec); int desireHeight = 0; for (int I = 0; I <cCount; I ++) {View child = getChildAt (I); measureChild (child, widthMeasureSpec, heightMeasureSpec); desireHeight + = child. getMeasuredHeight ();} setMeasuredDimension (desireWidth, desireHeight);}/*** click the item event to callback to the listener * @ author rander */public interface OnExpandItemClick {void onItemClick (int position ); void onBottomClick ();} private OnExpandItemClick mOnExpandItemClick; public void setOnExpandItemClick (OnExpandItemClick onExpandItemClick) {this. mOnExpandItemClick = onExpandItemClick ;}}
       
      
     
    
   
  

The layout of this view is as follows:


  
      
       
        
    
   
      
   

The layout of items in the Gridview is R. layout. gridview_item, which is a Button.


  

After analysis, write the code.

2. Implementation of the subject Control
The main control I mentioned is the implementation of the control function.
First, analyze what the main control contains
1) How many filtering items are listed <\ View>. This View is the ExpandleItemView defined above. It is compatible with the parent class programming. Some people also say that all the filtering items can reuse a View. Yes, but there is no need to bother yourself.
2) There is a row of buttons above, so List <\ View> is required for saving. Here I am using ToggleButton. For parent class programming, View is used.
3) When we click, we always remember which filter item is currently selected. So I defined a ToggleButton to record the Current Filter item mSelectToggleBtn.
4) PopupWindow is used for content pop-up. Of course, a variable is required.
5) There are two other variables. Do you find that the color of the selected and unselected titles is different? Therefore, define the color of the selected titles and the color of the unselected titles for the two variables.

Summary: in fact, this is also the property of the main control. Of course, here I have defined two variables to record the width and height attributes of PopupWindow, which is not necessary.

OK. The implementation code is as follows:

Package com. example. expandableview; import java. util. arrayList; import java. util. list; import com. example. expandableview. expandleItemView. onExpandItemClick; import android. content. context; import android. graphics. color; import android. graphics. drawable. bitmapDrawable; import android. util. attributeSet; import android. view. layoutInflater; import android. view. view; import android. widget. linearLayout; import android. widget. popupWindow; import android. widget. popupWindow. onDismissListener; import android. widget. relativeLayout; import android. widget. toggleButton; public class ExpandableView extends LinearLayout implements OnExpandItemClick {/** record the selected ToggleButton */private ToggleButton mSelectToggleBtn;/** filter */private List
  
   
MToggleButtons = new ArrayList <> ();/** filter Item Set */private List
   
    
MPopupviews;/** popupwindow display width */private int mDisplayWidth;/** popupwindow display height */private int mDisplayHeight; /** pop up the filtering content using PopupWindow */private PopupWindow mPopupWindow; private Context mContext;/** normal font color of toggleButton */int mNormalTextColor = getResources (). getColor (R. color. gray);/** toggleButton selected font Color */int mSelectTextColor = Color. RED; public ExpandableView (Context context, AttributeSet attrs, int defStyleAttr) {super (context, attrs, defStyleAttr); init ();} public ExpandableView (Context context, AttributeSet attrs) {this (context, attrs,-1);} public ExpandableView (Context context) {this (context, null);} private void init () {setOrientation (LinearLayout. HORIZONTAL); mDisplayWidth = getResources (). getDisplayMetrics (). widthPixels; mDisplayHeight = getResources (). getDisplayMetrics (). heightPixels; mContext = getContext (); setBackgroundResource (R. drawable. choosearea_bg_right);}/*** initialize the data and layout, and do the following: 1. based on the number of filtering items, the top row of ToggleButton 2 is dynamically added. set the monitoring event for each ToggleButton * 3. toggleButton. the setTag (I) clause is very important. We retrieve the View data according to this tag. 4. ** @ param views */public void initViews (List
    
     
Views) {mPopupviews = new ArrayList <> (); LayoutInflater inflater = (LayoutInflater) mContext. getSystemService (Context. LAYOUT_INFLATER_SERVICE); for (int I = 0; I <views. size (); I ++) {ExpandleItemView view = views. get (I); view. setOnExpandItemClick (this); final RelativeLayout r = new RelativeLayout (mContext); RelativeLayout. layoutParams rl = new RelativeLayout. layoutParams (RelativeLayout. layoutPar Ams. MATCH_PARENT, RelativeLayout. layoutParams. WRAP_CONTENT); r. addView (view, rl); mPopupviews. add (r); final ToggleButton toggleButton = (ToggleButton) inflater. inflate (R. layout. toggle_button, this, false); toggleButton. setText (view. getTitle (); mToggleButtons. add (toggleButton); addView (toggleButton); toggleButton. setTag (I); toggleButton. setOnClickListener (new OnClickListener () {@ Override public v Oid onClick (View v) {/** record the selected ToggleButton. It is easy to do anything with this */mSelectToggleBtn = toggleButton; showPopWindow ();}}); /*** click the outside of popupwindow to hide the popupwindow. This r is a click event that wraps an ExpandleItemView * If the user points to the range of ExpandleItemView, the click event is set to ExpandleItemView, if a point is placed out of * ExpandleItemView, r processing is available. The processing method is to contract */r. setOnClickListener (new OnClickListener () {@ Override public void onClick (View v) {onPressBack ();} private void onPress Back () {hidePopWindow () ;}}) ;}/ *** hide popupWindow and reset ToggleButton font color */private void hidePopWindow () {if (mPopupWindow! = Null) {mPopupWindow. dismiss ();} if (mSelectToggleBtn! = Null) {mSelectToggleBtn. setTextColor (mNormalTextColor); mSelectToggleBtn. setChecked (false) ;}}/*** display popupWindow */private void showPopWindow () {if (null = mPopupWindow) {mPopupWindow = new PopupWindow (mPopupviews. get (int) mSelectToggleBtn. getTag (), mDisplayWidth, mDisplayHeight);/** listen to the shrinking of popupWindow and reset the font color */mPopupWindow. setOnDismissListener (new OnDismissListener () {@ Override publi C void onDismiss () {if (mSelectToggleBtn! = Null) {mSelectToggleBtn. setTextColor (mNormalTextColor); mSelectToggleBtn. setChecked (false) ;}}); mPopupWindow. setAnimationStyle (R. style. popupWindowAnimation); mPopupWindow. setFocusable (true); mPopupWindow. setOutsideTouchable (true); mPopupWindow. setBackgroundDrawable (new BitmapDrawable ();} else {mPopupWindow. setContentView (mPopupviews. get (int) mSelectToggleBtn. getTag ();} if (mPopupWindo W. isShowing () {hidePopWindow ();} When else {/** is displayed, set it to the selected color */mSelectToggleBtn. setTextColor (mSelectTextColor); mPopupWindow. showAsDropDown (mToggleButtons. get (0), 0, 0) ;}/ *** the callback for the selected Item. Note that the filter Item view for Tag usage is obtained based on tag, because the tag of mSelectToggleBtn is the view Index * mSelectToggleBtn displays the filtered content */@ Override public void onItemClick (int position) {hidePopWindow (); if (null! = MSelectToggleBtn) {int selectBtnIndex = (int) mSelectToggleBtn. getTag (); mSelectToggleBtn. setText (ExpandleItemView) (RelativeLayout) mPopupviews. get (selectBtnIndex )). getChildAt (0 ))). getmGridviewDatas (). get (position) ;}}/*** click the callback mSelectToggleBtn at the bottom of the button to display the filtered content */@ Override public void onBottomClick () {hidePopWindow (); if (null! = MSelectToggleBtn) {int selectBtnIndex = (int) mSelectToggleBtn. getTag (); mSelectToggleBtn. setText (ExpandleItemView) (RelativeLayout) mPopupviews. get (selectBtnIndex )). getChildAt (0 ))). getTitle ()));}}}
    
   
  

The preceding view of a single ToggleButton R. layout. toggle_button is as follows:


  
  

The following figure shows the layout:


      
       
   
  

The Activity code is as follows:

Package com. example. expandableview; import java. util. arrayList; import java. util. arrays; import java. util. linkedHashMap; import java. util. map; import android. app. activity; import android. OS. bundle; public class MainActivity extends Activity {private ExpandableView mExpandableView; private Map
  
   
MExpandleItemViews; private String [] mColleages = {"A school", "B school", "C school", "D school", "E school", "F school ", "G school", "H school", "I school", "J school"}; private String [] mments ments = {"A", "B ", "C", "D", "E", "F", "G", "H", "I "}; private String [] mProfessions = {"A major", "B major", "C major", "D major", "E Major", "F Major "}; private String [] mClasses = {"Class A", "Class B", "Class C", "Class D", "Class E "}; @ Override protected void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); setContentView (R. layout. activity_main); mExpandableView = (ExpandableView) findViewById (R. id. expandview); mExpandleItemViews = new LinkedHashMap <> (); // do not ask why I use it because I want to use LinkedHashMap mExpandleItemViews. put ("", new ExpandleItemView ("", this, Arrays. asList (mColleages); mExpandleItemViews. put ("Faculty", new ExpandleItemView ("Faculty", this, Arrays. asList (mments ments); mExpandleItemViews. put ("professional", new ExpandleItemView ("professional", this, Arrays. asList (mProfessions); mExpandleItemViews. put ("class", new ExpandleItemView ("class", this, Arrays. asList (mClasses); mExpandableView. initViews (new ArrayList <> (mExpandleItemViews. values ()));}}
  

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.