Android自定義控制元件:將ViewPager封裝自己的TabPager控制元件
阿新 • • 發佈:2019-02-02
用途
最近專案頁面中經常出現諸如下圖的控制元件,如果為每個頁面分別寫一個將會造成非常多的重複程式碼,不利於專案的閱讀和維護,也會使專案變得非常凌亂。所以,對於這種情況我們可以進行一定的抽取,傳入相關資料後自動顯示到控制元件上。
思路
由上圖可知,我們需要上面的Tab作為指示,下面是類似輪播圖ViewPager。我們需要實現點選Tab切換到相應輪播圖頁面,同時滾動Page上面的Tab做相應的變化。
此時我們要動態填充上面Tab的內容以及輪播圖的內容。所以我把這兩塊建立了一個組合控制元件。Tab用一條LinearLayout,下面是ViewPager。同時提供資料介面,分別用於傳入Tab和ViewPager內容。
此處Tab分為背景和內容,背景是控制元件統一的,可以封裝在控制元件內部設定,所以我們要傳入文字的相關部分,這裡我使用傳入TextView。
ViewPager的內容,我們封裝在一個Holder中,Holder可以提供顯示內容及其資料。
有了這兩個內容,我們就可以以適當的方e式將內容分別填充到上面的LinearLayout中和ViewPager中。
具體做法及關鍵程式碼
主要涉及的問題
- Tab動態加入LinearLayout時佈局問題
- Tab的滑動與ViewPager的關聯
主要程式碼
git
呼叫方法及效果
假設我們需要四個Tab
private void initView(){
//構造Tab
TextView tab1 = new TextView(MainActivity.this);
tab1.setText("TAB1");
TextView tab2 = new TextView(MainActivity.this);
tab2.setText("TAB2");
TextView tab3 = new TextView(MainActivity.this );
tab3.setText("TAB3");
TextView tab4 = new TextView(MainActivity.this);
tab4.setText("TAB4");
//加入Tab
mMySlidingTabPager.addTab(tab1);
mMySlidingTabPager.addTab(tab2);
mMySlidingTabPager.addTab(tab3);
mMySlidingTabPager.addTab(tab4);
//建立頁面holder
ViewHolder1 holder1 = new ViewHolder1();
ViewHolder2 holder2 = new ViewHolder2();
ViewHolder3 holder3 = new ViewHolder3();
ViewHolder4 holder4 = new ViewHolder4();
//加入頁面holder
mMySlidingTabPager.addHolder(holder1);
mMySlidingTabPager.addHolder(holder2);
mMySlidingTabPager.addHolder(holder3);
mMySlidingTabPager.addHolder(holder4);
//頁面填充 這裡就可以顯示啦!!!
mMySlidingTabPager.start();
}
ViewHolder
/**
* 自繪控制元件封裝類
* Created by vonchenchen on 2015/11/3 0003.
*/
public abstract class BaseWidgetHolder<T> {
protected View mRootView;
public abstract View initView();
public abstract void refreshView(T data);
public BaseWidgetHolder(){
mRootView = initView();
mRootView.setTag(this);
}
public View getRootView(){
return mRootView;
}
}
控制元件實現
/**
* Created by vonchenchen on 2015/11/19 0019.
*/
public class MySlidingTabPager extends RelativeLayout{
private Context mCtx;
/** Tab佈局 */
private LinearLayout mTabsLayout;
/** ViewPager */
private ViewPager mContentViewPager;
private List<TextView> mTabList;
private List<BaseWidgetHolder> mHolderList;
private MyPagerAdapter mMyPagerAdapter;
private int mRecordPosition = -1;
public MySlidingTabPager(Context context) {
super(context);
this.mCtx = context;
}
public MySlidingTabPager(Context context, AttributeSet attrs) {
super(context, attrs);
this.mCtx = context;
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
View.inflate(mCtx, R.layout.layout_slidingtabpager, this);
mTabsLayout = (LinearLayout) findViewById(R.id.ll_tabs);
mContentViewPager = (ViewPager) findViewById(R.id.vp_content);
mTabList = new ArrayList<TextView>();
mHolderList = new ArrayList<BaseWidgetHolder>();
//監聽ViewPager滾動
mContentViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
//ViewPager滑動 對應Tab選擇
updateTab(position, false);
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
}
/**
* 新增Tab
* @param tab
*/
public void addTab(TextView tab){
mTabList.add(tab);
}
/**
* 新增holder
* @param holder
*/
public void addHolder(BaseWidgetHolder holder){
mHolderList.add(holder);
}
/**
* 開啟顯示
*/
public void start(){
initTabView();
initViewPager();
}
private void initTabView(){
//設定Layout引數,用於新增新的Tab
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0, dip2px(MyApplication.getContext(), 40));
params.weight = 1;
for(int i=0; i<mTabList.size(); i++){
TextView view = mTabList.get(i);
view.setGravity(Gravity.CENTER);
final int position = i;
view.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
mContentViewPager.setCurrentItem(position);
updateTab(position, true);
}
});
//將TextView加入到LinearLayout上
mTabsLayout.addView(view, params);
setViewUnSelected(view, i);
}
//初始化預設Tab顏色及其位置
mRecordPosition = 0;
setViewSelectd(mTabList.get(0), 0);
}
private void updateTab(int position, boolean isTouchTab){
if(position != mRecordPosition){
setViewSelectd(mTabList.get(position), position);
}
if(mRecordPosition >= 0 && !isTouchTab){
setViewUnSelected(mTabList.get(mRecordPosition), mRecordPosition);
}
mRecordPosition = position;
}
/**
* 當Pager被選擇時設定對應Tab的顏色
* @param view
* @param position
*/
private void setViewSelectd(View view, int position){
if(position == 0){
view.setBackgroundResource(R.drawable.shape_detail_rb_left_blue);
}else if(position == mTabList.size()-1){
view.setBackgroundResource(R.drawable.shape_detail_rb_right_blue);
}else{
view.setBackgroundResource(R.drawable.shape_detail_rb_mid_blue);
}
}
/**
* 取消Tab的選中顏色
* @param view
* @param position
*/
private void setViewUnSelected(View view, int position){
if(position == 0) {
view.setBackgroundResource(R.drawable.shape_detail_rb_left_white);
}else if(position == mTabList.size()-1){
view.setBackgroundResource(R.drawable.shape_detail_rb_right_white);
}else{
view.setBackgroundResource(R.drawable.shape_detail_rb_mid_white);
}
}
private void initViewPager(){
mMyPagerAdapter = new MyPagerAdapter();
mContentViewPager.setAdapter(mMyPagerAdapter);
}
public class MyPagerAdapter extends PagerAdapter {
@Override
public int getCount() {
return mTabList.size();
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view==object;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View)object);
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
container.addView(mHolderList.get(position).getRootView());
return mHolderList.get(position).getRootView();
}
}
private int dip2px(Context context, float dpValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale);
}
}