Android可篩選的彈窗控件CustomFiltControl
本文實例為大家分享了Android彈窗控件CustomFiltControl的使用方法,供大家參考,具體內(nèi)容如下
效果:
起初踩的坑:
剛開始是因為項目中需要用到篩選的功能,以前也遇到過但都是其他同事做的,而我看他們的實現(xiàn)大多都是自己一個個的碼布局,然后做事件處理很麻煩,還有的是通過網(wǎng)上的一些線性排列控件自己組合實現(xiàn)的。
如今自己遇到了我開始想的也是通過LinearLayout動態(tài)去添加選項,title部分就是也是動態(tài)添加,一個打的LinearLayout包兩個小的,然后在小的里面又包很多選項,但是遇到要換行的時候又需要添加一個LinearLayout,也就是但是有個問題,布局繁瑣,得不到很好的復(fù)用。
后面突然想到了GridLayout,然后又使用了LinearLayout+GridLayout,對GridLayout是可以避免在你換行的時候去計算,只要你設(shè)置好行列,它會自動換行,這是確實實現(xiàn)了上面的效果,但是博主寫好了又發(fā)現(xiàn)不夠完美,既然GridLayout能自動換行,又可以一個站多行多列,為什么不把title也放到GridLayout中呢,有了這個想法,又來修改,在計算行列的時候確實遇到了阻礙,不過終究是完成了,最后封裝在了popuwindow中直接調(diào)用。
看看主要實現(xiàn)吧:
package com.zzq.mack.customfiltcontrol; import android.content.Context; import android.graphics.Color; import android.support.v7.widget.GridLayout; import android.text.TextUtils; import android.view.Gravity; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.widget.LinearLayout; import android.widget.PopupWindow; import android.widget.TextView; import android.widget.Toast; import com.zzq.mack.customfiltcontrol.model.FiltModel; import java.util.List; /** * Author:xqt * Email:zzq1573@gmail.com * Date:2018/3/31 0031 11:24 * Description:篩選彈框 版權(quán)所有轉(zhuǎn)載請注明出處 */ public class FiltPopuWindow extends PopupWindow{ public FiltPopuWindow(Context context,View view){ //這里可以修改popupwindow的寬高 super(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT); setContentView(view); initViews(); } private void initViews() { setAnimationStyle(R.style.popwin_anim_style); //setBackgroundDrawable(new ColorDrawable(0x00000000)); setFocusable(true); setOutsideTouchable(true); } public static class Builder { private Context context; private List<FiltModel> listData; private int columnCount; private GridLayout rootGridLayout; private LinearLayout contextll; //背景顏色 private int colorBg = Color.parseColor("#F8F8F8"); private int titleTextSize = 14;//SP private int tabTextSize = 14;//SP private int titleTextColor = Color.parseColor("#333333");//標(biāo)題字體顏色 private int tabTextColor = R.color.fit_item_textcolor;//選項字體顏色 private int tabBgDrawable = R.drawable.item_lable_bg_shape;//選項背景顏色 //當(dāng)前加載的行數(shù) private int row = -1; private FiltPopuWindow mFiltPopuWindow; public Builder(Context context) { this.context = context; } /** * 設(shè)置數(shù)據(jù)源 * @return */ public Builder setDataSource(List<FiltModel> listData) { this.listData = listData; return this; } public Builder setColumnCount(int columnCount){ this.columnCount = columnCount; return this; } public Builder setColorBg(int color){ colorBg = context.getResources().getColor(color); return this; } public Builder setTitleTextSize(int titleTextSize) { this.titleTextSize = titleTextSize; return this; } public Builder setTabTextSize(int tabTextSize) { this.tabTextSize = tabTextSize; return this; } public Builder setTitleTextColor(int titleTextColor) { this.titleTextColor = titleTextColor; return this; } public Builder setTabTextColor(int tabTextColor) { this.tabTextColor = tabTextColor; return this; } public Builder setTabBgDrawable(int tabBgDrawable) { this.tabBgDrawable = tabBgDrawable; return this; } public Builder build(){ newItemLayout(getRowCount(),columnCount); for (int i = 0; i < listData.size(); i++){ ++row; TextView view = new TextView(context); view.setText(listData.get(i).getTypeName()); view.setTextColor(titleTextColor); view.setTextSize(titleTextSize); //配置列 第一個參數(shù)是起始列標(biāo) 第二個參數(shù)是占幾列 title(篩選類型)應(yīng)該占滿整行,so -> 總列數(shù) GridLayout.Spec columnSpec = GridLayout.spec(0,columnCount); //配置行 第一個參數(shù)是起始行標(biāo) 起始行+起始列就是一個確定的位置 GridLayout.Spec rowSpec = GridLayout.spec(row); //將Spec傳入GridLayout.LayoutParams并設(shè)置寬高為0或者WRAP_CONTENT,必須設(shè)置寬高,否則視圖異常 GridLayout.LayoutParams lp = new GridLayout.LayoutParams(rowSpec, columnSpec); lp.width = GridLayout.LayoutParams.WRAP_CONTENT; lp.height = GridLayout.LayoutParams.WRAP_CONTENT; lp.setGravity(Gravity.LEFT | Gravity.CENTER_VERTICAL); lp.bottomMargin = context.getResources().getDimensionPixelSize(R.dimen.dp_8); rootGridLayout.addView(view,lp); //添加選項 addTabs(listData.get(i),i); } return this; } private void newItemLayout(int rowCount,int columnCount){ contextll = new LinearLayout(context); contextll.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); contextll.setBackgroundColor(context.getResources().getColor(R.color.color_33000000)); contextll.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (mFiltPopuWindow != null){ mFiltPopuWindow.dismiss(); //點擊外部消失 } } }); rootGridLayout = new GridLayout(context); LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); rootGridLayout.setOrientation(GridLayout.HORIZONTAL); rootGridLayout.setRowCount(rowCount); rootGridLayout.setColumnCount(columnCount); rootGridLayout.setBackgroundColor(colorBg); rootGridLayout.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { return true; } }); int pandd = context.getResources().getDimensionPixelSize(R.dimen.dp_10); lp.weight = 1; rootGridLayout.setPadding(pandd,pandd,pandd,pandd); contextll.addView(rootGridLayout,lp); } /** * 添加選項 * @param model */ private void addTabs(final FiltModel model, final int titleIndex){ List<FiltModel.TableMode> tabs = model.getTabs(); for (int i = 0; i < tabs.size(); i++){ if (i % columnCount == 0){ row ++; } final FiltModel.TableMode tab = tabs.get(i); final TextView lable = new TextView(context); lable.setTextColor(context.getResources().getColorStateList(tabTextColor)); lable.setBackgroundDrawable(context.getResources().getDrawable(tabBgDrawable)); lable.setSingleLine(true); lable.setGravity(Gravity.CENTER); lable.setEllipsize(TextUtils.TruncateAt.MIDDLE); //這里可以自行修改tab框框的大小 int panddT = context.getResources().getDimensionPixelSize(R.dimen.dp_2); int panddL = context.getResources().getDimensionPixelSize(R.dimen.dp_8); lable.setPadding(panddL,panddT,panddL,panddT); lable.setTextSize(tabTextSize); rootGridLayout.addView(lable,getItemLayoutParams(i,row)); lable.setText(tab.name); if (tabs.get(i) == model.getTab()){ lable.setSelected(true); } lable.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //lable.setSelected(true); if (tab != model.getTab()){ //清空上次選中 rootGridLayout.getChildAt(getIndex(model,titleIndex)).setSelected(false); //設(shè)置當(dāng)前選中 model.setTab(tab); lable.setSelected(true); } } }); } } private GridLayout.LayoutParams getItemLayoutParams(int i,int row){ //使用Spec定義子控件的位置和比重 GridLayout.Spec rowSpec = GridLayout.spec(row,1f); GridLayout.Spec columnSpec = GridLayout.spec(i%columnCount,1f); //將Spec傳入GridLayout.LayoutParams并設(shè)置寬高為0,必須設(shè)置寬高,否則視圖異常 GridLayout.LayoutParams lp = new GridLayout.LayoutParams(rowSpec, columnSpec); lp.width = 0; lp.height = GridLayout.LayoutParams.WRAP_CONTENT; lp.bottomMargin = context.getResources().getDimensionPixelSize(R.dimen.dp_8); if(i % columnCount == 0) {//最左邊 lp.leftMargin = context.getResources().getDimensionPixelSize(R.dimen.dp_10); lp.rightMargin = context.getResources().getDimensionPixelSize(R.dimen.dp_20); }else if((i + 1) % columnCount == 0){//最右邊 lp.rightMargin = context.getResources().getDimensionPixelSize(R.dimen.dp_10); }else {//中間 lp.rightMargin = context.getResources().getDimensionPixelSize(R.dimen.dp_20); } return lp; } /** * 獲取當(dāng)前選中tab的 在整個GridLayout的索引 * @return */ private int getIndex(FiltModel model,int titleIndex){ int index = 0; for (int i = 0; i < titleIndex; i++){ //計算當(dāng)前類型之前的元素所占的個數(shù) title算一個 index += listData.get(i).getTabs().size() + 1; } //加上當(dāng)前 title下的索引 FiltModel.TableMode tableModel = model.getTab(); index += model.getTabs().indexOf(tableModel) + 1; return index; } /** * 計算行數(shù) * @return */ private int getRowCount(){ int row = 0; for (FiltModel model : listData){ //計算當(dāng)前類型之前的元素所占的個數(shù) title算一個 row ++; int size = model.getTabs().size(); row += (size / columnCount) + (size % columnCount > 0 ? 1 : 0) ; } return row; } public FiltPopuWindow createPop(){ if (listData == null || listData.size() == 0){ try { throw new Exception("沒有篩選條件"); } catch (Exception e) { Toast.makeText(context,e.getMessage(),Toast.LENGTH_SHORT).show(); e.printStackTrace(); } return null; } mFiltPopuWindow = new FiltPopuWindow(context,contextll); return mFiltPopuWindow; } } }
通過設(shè)置columnCount的大小可以改變列數(shù),測試2,3,4,5沒問題,只是列數(shù)越多就越擠,這是必然的。
希望對你有幫助,有問題歡迎給我留言。
這里準(zhǔn)備了一個demo作為參考
GitHub:CutomFiltControl
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android實現(xiàn)可復(fù)用的篩選頁面
- Android中 TeaScreenPopupWindow多類型篩選彈框功能的實例代碼
- Android實現(xiàn)簡單下拉篩選框
- android仿京東商品屬性篩選功能
- 可支持快速搜索篩選的Android自定義選擇控件
- Android 仿京東側(cè)滑篩選實例代碼
- Android Handler之消息循環(huán)的深入解析
- Android開發(fā)筆記之:消息循環(huán)與Looper的詳解
- Android實現(xiàn)圖片循環(huán)播放的實例方法
- RecyclerView+SnapHelper實現(xiàn)無限循環(huán)篩選控件
相關(guān)文章
Android中HttpURLConnection與HttpClient的使用與封裝
這篇文章主要介紹了Android中HttpURLConnection與HttpClient的使用以及封裝方法,感興趣的小伙伴們可以參考一下2016-03-03Android嵌套滾動和協(xié)調(diào)滾動的多種實現(xiàn)方法
嵌套的滾動主要方式就是這些,這些簡單的效果我們用協(xié)調(diào)滾動,如?CoordinatorLayout?也能實現(xiàn)同樣的效果,這篇文章主要介紹了Android嵌套滾動和協(xié)調(diào)滾動的多種實現(xiàn)方法,需要的朋友可以參考下2022-06-06Android實現(xiàn)Recycleview懸浮粘性頭部外加右側(cè)字母導(dǎo)航
這篇文章主要為大家詳細(xì)介紹了Android實現(xiàn)Recycleview懸浮粘性頭部外加右側(cè)字母導(dǎo)航,具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-06-06RXjava網(wǎng)絡(luò)獲取圖片數(shù)據(jù)的方法
這篇文章主要為大家詳細(xì)介紹了RXjava網(wǎng)絡(luò)獲取圖片數(shù)據(jù),具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-08-08Android編程實現(xiàn)仿QQ發(fā)表說說,上傳照片及彈出框效果【附demo源碼下載】
這篇文章主要介紹了Android編程實現(xiàn)仿QQ發(fā)表說說,上傳照片及彈出框效果,涉及Android動畫特效的相關(guān)實現(xiàn)技巧,并附帶demo源碼供讀者下載參考,需要的朋友可以參考下2017-01-01詳解 Kotlin Reference Basic Types, String, Array and Imports
這篇文章主要介紹了詳解 Kotlin Reference Basic Types, String, Array and Imports的相關(guān)資料,需要的朋友可以參考下2017-06-06android在連拍菜單中增加連拍張數(shù)選項功能實現(xiàn)代碼
想要增加連拍張數(shù)選項需要在entries, entryvalues中添加兩項,同時在mtk_strings.xml中添加相應(yīng)的字符串,具體如下,感興趣的朋友可以參考下哈2013-06-06