天天看點

android高仿美團篩選控件,Android高仿美團首頁分類按鈕

慣例,先上GIF

android高仿美團篩選控件,Android高仿美團首頁分類按鈕

栗子.gif更新v1.1版本 2017-6-2 11:55:30

詳見github

一、使用姿勢

1、引入(使用Gradle或者Maven)

1)Gradleallprojects {

repositories {

...

maven { url 'https://jitpack.io' }

}

}

dependencies {

compile 'com.github.FJ917:FJMtSortButton:v1.1'

}

2)Maven

jitpack.io

https://jitpack.io

com.github.FJ917

FJMtSortButton

v1.1

2、使用方法

1)xml檔案

android:id="@+id/soreButton"

android:background="#ffffff"

android:layout_width="match_parent"

android:layout_height="170dp"/>

2)java檔案

1.對自定義控件做一些設定//設定界面監聽

soreButton.setViewControl(this);

//添加界面到list

list = new ArrayList<>();

list.add(R.layout.viewpager_page);

list.add(R.layout.viewpager_page);

list.add(R.layout.viewpager_page_text);

//控件相關設定

soreButton

//設定選中和未選中訓示器圖示

.setIndicator(R.drawable.radio1,R.drawable.radio2)

//設定訓示器半間距px

.setDistance(10)

//設定view組

.setView(list)

.init();

将layout的布局add進去list中,然後調用setView方法把list傳過去,

還提供了設定訓示器圖示的方法,以及訓示器間距的方法,最後必須調用初始化方法init進行初始化

這是其中的一個layout布局,其實這裡可以添加任意布局檔案進去,是不是比美團更靈活呢?

布局R.layout.viewpager_page<?xml  version="1.0" encoding="utf-8"?>

android:layout_width="match_parent"

android:layout_height="match_parent"

android:padding="5dp"

android:background="#ffffff" >

android:id="@+id/gridView"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:gravity="center"

android:horizontalSpacing="5dp"

android:numColumns="5"

android:scrollbars="none"

android:stretchMode="columnWidth"

android:verticalSpacing="10dp" />

2.設定soreButton監聽事件(具體的可以參考GIt上面的Demo,Git位址文章末尾)public class MainActivity extends AppCompatActivity implements ViewControl {

private SoreButton soreButton;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

soreButton = (SoreButton) findViewById(R.id.soreButton);

soreButton.setViewControl(this);

}

@Override

public void setView(View view, final int type) {

//這裡會傳回前面設定進去的View及對應的type,然後就可以進行操作了

}

}

劃重點:上面的list中可以傳入任意layout布局,然後通過接口回掉拿到View。比美團更加靈活。好了使用姿勢已經講完了,伸手可以撤退了~ 接下來開始講講實作原理

二、實作原理

1. 需求分析

android高仿美團篩選控件,Android高仿美團首頁分類按鈕

需求.png

界面:分為兩部分,上面的按鈕以及下面的訓示點。上面使用ViewPager作為View的容器,下面的訓示器用LinearLayout将動态建立的ImageView添加進去。

ViewPager中的按鈕使用GridView來做,當然這一部分我們需要做的靈活些,不一定隻放按鈕,也可以方其他View,超越美團,//手動滑稽。

重點:通過自定義組合控件的方式來進行封裝,友善以後的使用。

2.下面開始封裝

1)xml<?xml  version="1.0" encoding="utf-8"?>

android:layout_width="match_parent"

android:orientation="vertical"

android:layout_height="match_parent">

android:id="@+id/viewPager"

android:layout_weight="1"

android:layout_width="match_parent"

android:layout_height="0dp" />

android:layout_below="@+id/viewPager"

android:id="@+id/llIndicator"

android:layout_width="match_parent"

android:layout_height="20dp"

android:background="#ffffff"

android:gravity="center"

android:orientation="horizontal" >

和普通的布局沒啥差別,外層LinearLayout垂直布局,其中有ViewPager作為滑動切換的容器,内部的LinearLayout作為訓示器容器。

2)自定義控件SoreButton.java

設定了預設值變量,以及控件和接口定義Context mContext;

private ViewPager viewPager;

private LinearLayout llIndicator;

//選中圖檔

private int RadioSelect = R.drawable.radio_select;

//未選中圖檔

private int RadioUnselected = R.drawable.radio_unselected;

//圓點間距

private int distance = 10;

List listSoreView = new ArrayList<>();

View soreView;

private List listView;

//接口

private ViewControl viewControl;

//設定接口

public void setViewControl(ViewControl viewControl) {

this.viewControl = viewControl;

}

拿到了自定義控件的布局中ViewPager和LinearLayout,并且設定了一個空布局。public SoreButton(Context context, AttributeSet attrs) {

super(context, attrs);

mContext = context;

LayoutInflater.from(context).inflate(R.layout.anfq_sore_button, this, true);

viewPager = (ViewPager) findViewById(R.id.viewPager);

llIndicator = (LinearLayout) findViewById(R.id.llIndicator);

//設定空布局

listView = new ArrayList<>();

listView.add(R.layout.viewpager_default);

}

對外提供的參數設定方法,當調用了init()方法後,會調用initViewPager方法進行ViewPager的初始化。

public SoreButton setDistance(int distance){

this.distance = distance;

return this;

}

public SoreButton setIndicator(int radioSelect,int radioUnselected){

//選中圖檔

RadioSelect = radioSelect;

//未選中圖檔

RadioUnselected = radioUnselected;

return this;

}

public SoreButton setView(List listView){

this.listView = listView;

return this;

}

public SoreButton init(){

initViewPager();

return this;

}

接下來我們看看initViewPager中都做了那些操作//初始化ViewPager

private void initViewPager(){

listSoreView = new ArrayList<>();

LayoutInflater layoutInflater = (LayoutInflater)

mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

int size = listView.size();

for (int i = 0; i 

//循環拿到傳入的View

soreView = layoutInflater.inflate(listView.get(i), null);

//通過接口回掉的形式傳回目前的View,實作接口後開源拿到每個View然後進行操作

if (viewControl!=null){

viewControl.setView(soreView,i);

}

//将擷取到的View添加到List中

listSoreView.add(soreView);

}

//設定viewPager的Adapter

viewPager.setAdapter(new ViewPagerAdapter(listSoreView));

//初始化LinearLayout,加入訓示器

initLinearLayout(viewPager, size, llIndicator);

}

因為之前調用了setView方法,傳入了一組布局,我們通過循環來拿到這組View并添加到list中,然後設定到viewPager的Adapter,然後調用initLinearLayout方法初始化訓示器。

接下來我們來看initLinearLayout中又做了那些操作

private void initLinearLayout(ViewPager viewPager, int pageSize, LinearLayout linearLayout) {

//定義數組放置訓示器的點,pageSize是View個數

final ImageView[] imageViews = new ImageView[pageSize];

for (int i = 0; i 

//建立ImageView

ImageView image = new ImageView(mContext);

//将ImageView放入數組

imageViews[i] = image;

//預設選中第一個

if (i == 0) {

//選中的點

image.setImageResource(RadioSelect);

} else {

//未選中的點

image.setImageResource(RadioUnselected);

}

//設定寬高

LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(

LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);

params.setMargins(distance, 0, distance, 0);

//将點添加到LinearLayout中

linearLayout.addView(image, params);

}

//ViewPager的滑動事件

viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {

@Override

public void onPageScrollStateChanged(int arg0) {}

@Override

public void onPageScrolled(int arg0, float arg1, int arg2) {}

@Override

public void onPageSelected(int arg0) {

//arg0目前ViewPager

for (int i = 0; i 

//設定為選中的點

imageViews[arg0].setImageResource(RadioSelect);

//判斷目前的點i如果不等于目前頁的話就設定為未選中

if (arg0 != i) {

imageViews[i].setImageResource(RadioUnselected);

}

}

}

});

}

定義了一個數組,用來放置訓示器的點,通過循環pageSize來動态建立ImageView,然後判斷i來将第一頁的ImageView設定為選中的點,其餘設定為未選中的點。接着設定了寬高,然後添加到LinearLayout中。

當然這樣還不行,在viewPager滑動的時候我們得更新訓示器上的點

我們對ViewPager設定了監聽事件setOnPageChangeListener,在滑動的時候會調用onPageSelected,在這裡可以拿到目前頁,之後我們通過循環剛剛的數組,将目前頁對應的點設定為選中圖示,不等于目前頁的設定為未選中的點。

**然後就沒有然後了,封裝完成~

這樣就可以通過上面所說的方式,來使用這個自定義控件實作仿美團的效果,而且不止是仿美團的效果,可以傳入其他View,來實作其他效果。比如:稍加改動布局的話可以作為應用的啟動引導頁。

**總結:通過自定義組合控件,可以對一些常用的布局以及邏輯代碼進行封裝,以減少使用時代碼量,使得代碼更加簡潔。