1. 程式人生 > >android底部導航欄+viewPager+自定義view的簡單實現

android底部導航欄+viewPager+自定義view的簡單實現

Ps:導航欄直接用Android Design Library,導航欄的話用TabLayout實現,是比較方便快捷的方法。以下僅供初學者學習。。。。一年後回過來看寫的比較糟糕

這裡寫圖片描述

1首先我們要解決介面的問題,也就是先讓使用者能看到介面,再來搞定能不能用的問題是吧。首先是下面導航欄,我第第一反應就是想到一個ImageView+TextView的組合,也就是用到了組合控制元件,這裡我叫它phototext.xml。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent" xmlns:tools="http://schemas.android.com/tools">
<LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:layout_centerVertical
="true">
<ImageView android:id="@+id/photo" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_centerVertical="true" tools:src="@mipmap/ic_launcher"
/>
<TextView android:id="@+id/photo_text" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" tools:text="男"/> </LinearLayout> </RelativeLayout>

有了佈局檔案,那麼就要有java檔案嘛,因為自定義,不然的話上面佈局就是死的,不可以自己自定義了。java檔案自然也叫PhotoText.java,很好聽吧。。突然覺得我是取名字的天才。。。

public class PhotoText extends RelativeLayout {

    private final String TAG = "PHOTOTEXT";

    private ImageView iv;//圖片
    private TextView tv;//文字

//以下是自定義View自己可以設定的屬性
    private int mtextSize=15;
    private String mText;
    private Drawable mPhoto;
    private Drawable mBackGround;
    private ColorStateList mTextColor;

    public PhotoText(Context context, AttributeSet attrs) {
        super(context, attrs);
        LayoutInflater.from(context).inflate(R.layout.photo_text,this,true);

        TypedArray ta=context.obtainStyledAttributes(attrs, R.styleable.PhotoText);

        int n=ta.getIndexCount();
        for (int i=0;i<n;i++){
            int atrr = ta.getIndex(i);
            switch (atrr){
                case R.styleable.PhotoText_mText:
                    mText=ta.getString(atrr); break;
                case R.styleable.PhotoText_mphoto:
                    mPhoto=ta.getDrawable(atrr);break;
                case R.styleable.PhotoText_mBackGround:
                    mBackGround=ta.getDrawable(atrr);break;
                case R.styleable.PhotoText_mTextSize:
                    mtextSize=ta.getDimensionPixelSize(atrr,mtextSize);break;
                case R.styleable.PhotoText_mTextColor:
                    mTextColor=ta.getColorStateList(atrr);break;
            }
        }
        ta.recycle();

        iv= (ImageView) findViewById(R.id.photo);
        tv=(TextView)findViewById(R.id.photo_text);
        iv.setImageDrawable(mPhoto);
        tv.setText(mText);
        tv.setTextSize(mtextSize);
        tv.setTextColor(mTextColor!=null ? mTextColor : ColorStateList.valueOf(0xFF000000));
        setBackground(mBackGround);
    }

    public void setSelected(boolean is){
        iv.setSelected(is);
        tv.setSelected(is);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
    }

}

接下來就可以用了喔,也就是在mainActivity的佈局裡用activity_main.xml檔案裡嘍

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:custom="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:id="@+id/navigationBar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:background="#f3f1f1"
        android:layout_alignParentBottom="true">

        <view.PhotoText
            android:id="@+id/data_tab"
            android:layout_width="30dp"
            android:layout_height="60dp"
            android:layout_weight="1"
            custom:mTextSize="5dp"
            custom:mphoto="@drawable/data_tab_selected"
            custom:mText="資料"
            custom:mTextColor="@drawable/textcolor_tab"
            >
        </view.PhotoText>

        <view.PhotoText
            android:id="@+id/setting_tab"
            android:layout_width="30dp"
            android:layout_height="60dp"
            android:layout_weight="1"
            custom:mphoto="@drawable/setting_tab_selected"
            custom:mText="設定"
            custom:mTextColor="@drawable/textcolor_tab">
        </view.PhotoText>

    </LinearLayout>

    <android.support.v4.view.ViewPager
        android:id="@+id/content"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@id/navigationBar">
    </android.support.v4.view.ViewPager>

</RelativeLayout>

因為專案只用了兩個選項,所以導航欄只有兩個,要多加只需新增多PhotoText控制元件,並把weight都設為1就可以均分了,這裡用了viewpager為了實現像微信那樣左右滑動能切換選項卡,接下來就是java程式碼實現了,也就是主MainActivity.java了,先看程式碼嘛再講思路

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    //兩個選項
    PhotoText dataTab;
    PhotoText settingTab;

    FragmentManager fm;
    ViewPager viewPager;
    ArrayList<android.app.Fragment> fragmentsList;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        fm = getFragmentManager();
        fragmentsList = new ArrayList<>();
    }

    @Override
    protected void onStart() {
        super.onStart();
        fragmentsList.add(new Fragment1());
        fragmentsList.add(new Fragment2());
        dataTab= (PhotoText) findViewById(R.id.data_tab);
        settingTab= (PhotoText) findViewById(R.id.setting_tab);

        viewPager = (ViewPager) findViewById(R.id.content);
        FragmentPagerAdapter pagerAdapter = new FragmentPagerAdapter(fm) {
            @Override
            public android.app.Fragment getItem(int position) {
                return fragmentsList.get(position);

            }

            @Override
            public int getCount() {
                return fragmentsList.size();
            }

        };
        viewPager.setAdapter(pagerAdapter);
        viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                selectTab(position);
            }

            @Override
            public void onPageSelected(int position) {

            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });
        dataTab.setOnClickListener(this);
        settingTab.setOnClickListener(this);
        selectTab(0);
    }

    /*
    傳入0表示第一個tab被選擇
    1表示第二個變選中,設定selected
     */
    public void selectTab(int tab){
        switch (tab){
            case 0:
                dataTab.setSelected(true);
                settingTab.setSelected(false);
                break;
            case 1:
                dataTab.setSelected(false);
                settingTab.setSelected(true);
                break;
        }
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.data_tab:
                viewPager.setCurrentItem(0);
                break;
            case R.id.setting_tab:
                viewPager.setCurrentItem(1);
        }
    }
}

首先呢,我們需要viewpager的adapter,這裡用的是FragmentPagerAdapter,這個Adapter需要兩個Fragment,也就是我們在建立Adapter之前new出兩個Fragment並放在集合中,然後getFragmentManager()拿到碎片管理器,接下來把這兩個引數穿進去就可以用了,最後收尾工作就是設定以下,導航欄的監聽和viewpager的滑動監聽。。。over,