1. 程式人生 > >Toolbar動態設定menu選單,標題居中,menu和返回鍵點選事件

Toolbar動態設定menu選單,標題居中,menu和返回鍵點選事件

最近用toolbar,感覺使用非常麻煩,標題不能居中,設定點選事件也很麻煩,就自己封裝了一個toolbar;

1.首先解決標題不能居中的問題;

1)自定義一個xml檔案取名為itoolbar

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/itoolbar_content"
android:layout_width="wrap_content"
android:layout_height=
"wrap_content" android:layout_gravity="center" tools:textColor="#fff" tools:text="123" xmlns:tools="http://schemas.android.com/tools" > </TextView>
2)建立一個IToolbar繼承自Toolbar,並將view新增到IToolbar中
private void initView() {
    View view = LayoutInflater.from(context).inflate(R.layout.itoolbar, this, false
); mContent = view.findViewById(R.id.itoolbar_content); addView(view); setTitle("");//設定Toolbar自帶的標題為空 Toolbar.LayoutParams lp = (LayoutParams) view.getLayoutParams(); lp.gravity = Gravity.CENTER; this.setLayoutParams(lp); }
3)將mContent的值和Toolbar自帶的Title值,和顏色關聯起來就
//這裡直接拿的系統的styleable
TintTypedArray tta = TintTypedArray.obtainStyledAttributes
(context, attrs, R.styleable.Toolbar, defStyleAttr, 0); mContent.setTextColor(tta.getColor(R.styleable.Toolbar_titleTextColor, 0xffffffff)); mContent.setText(tta.getText(R.styleable.Toolbar_title)); tta.recycle();
4)在主佈局和Toolbar用法一樣,標題會居中顯示
<toolbar.ljj.com.toolbardemo.IToolbar
android:id="@+id/main_itoobar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?actionBarSize"
android:background="@color/colorPrimaryDark"
app:title="我是標題"
app:titleTextColor="#ffffff"
app:navigationIcon="@drawable/back"></toolbar.ljj.com.toolbardemo.IToolbar>

2.解決監聽事件,可以知道,不管是返回按鈕還是Menu選單按鈕,都是點選事件,分開寫實在太麻煩,我把他們整合成了一個事件;

final IToolbar iToolbar = findViewById(R.id.main_itoobar);
iToolbar.inflateMenu(R.menu.itoolbar);
iToolbar.setIToolbarCallback(new IToolbar.IToolbarCallback() {
    @Override
public void onClickListener(int pos) {
        switch (pos) {
            case 0:
                Log.v("TTT", "返回");
                break;
            case 1:
                Log.v("TTT", "選單1");
                break;
            case 2:
                Log.v("TTT", "選單2");
                break;
            case 3:
                Log.v("TTT", "選單3");
                break;
}
    }
});
這樣使用就可以了,它是從左往右排序;

3.接下來是動態設定Toolbar的Menu按鈕,直接呼叫initMenuView方法就好了,傳入的引數是要顯示的按鈕樣式,其他的隱藏。

findViewById(R.id.changeMenu).setOnClickListener(new View.OnClickListener() {
    @Override
public void onClick(View v) {
        if (issss) {
            iToolbar.initMenuView(1);
} else {
            iToolbar.initMenuView(0, 1, 2);
}
        issss = !issss;
}
});
在使用前要先呼叫
iToolbar.inflateMenu(R.menu.itoolbar);

最後上完整程式碼

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.XmlResourceParser;
import android.support.annotation.Nullable;
import android.support.v7.widget.TintTypedArray;
import android.support.v7.widget.Toolbar;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
 * 自定義Toolbar
 * Created by lijiajun on 2018/2/3.
 */
public class IToolbar extends Toolbar {

    private Context context;
    private TextView mContent;
    private IToolbarCallback iToolbarCallback;
//是否有返回鍵
private boolean haseBack;
//總MenuId
private List<Integer> menuId;
//顯示MenuPos
private List<Integer> showMenuPos;
    public interface IToolbarCallback {
        void onClickListener(int pos);
}

    public void setIToolbarCallback(IToolbarCallback iToolbarCallback) {
        this.iToolbarCallback = iToolbarCallback;
}

    public IToolbar(Context context) {
        this(context, null);
}

    public IToolbar(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, R.attr.toolbarStyle);
}

    @SuppressLint("RestrictedApi")
    public IToolbar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.context = context;
menuId = new ArrayList<>();
showMenuPos = new ArrayList<>();
        if (getNavigationIcon() != null) {
            haseBack = true;
}
        initView();
//這裡直接拿的系統的styleable
TintTypedArray tta = TintTypedArray.obtainStyledAttributes(context, attrs, R.styleable.Toolbar, defStyleAttr, 0);
mContent.setTextColor(tta.getColor(R.styleable.Toolbar_titleTextColor, 0xffffffff));
mContent.setText(tta.getText(R.styleable.Toolbar_title));
tta.recycle();
initListener();
}


    private void initView() {
        View view = LayoutInflater.from(context).inflate(R.layout.itoolbar, this, false);
mContent = view.findViewById(R.id.itoolbar_content);
addView(view);
setTitle("");//設定Toolbar自帶的標題為空
Toolbar.LayoutParams lp = (LayoutParams) view.getLayoutParams();
lp.gravity = Gravity.CENTER;
        this.setLayoutParams(lp);
}

    private void initListener() {

        if (haseBack) {
            setNavigationOnClickListener(new OnClickListener() {
                @Override
public void onClick(View v) {
                    if (iToolbarCallback != null) {
                        iToolbarCallback.onClickListener(0);
}
                }
            });
}
        if (getMenu() != null) {
            //如果設定了返回,則postion從1開始,否則從0開始
final int menCount = haseBack ? 1 : 0;
setOnMenuItemClickListener(new OnMenuItemClickListener() {
                @Override
public boolean onMenuItemClick(MenuItem item) {
                    for (int i = 0; i < menuId.size(); i++) {
                        for (int j = 0; j < showMenuPos.size(); j++) {
                            //判斷id值和位置設定點選事件;
if ((i == showMenuPos.get(j)) && (item.getItemId() == menuId.get(i)) && (iToolbarCallback != null)) {
                                iToolbarCallback.onClickListener(j + menCount);
}
                        }
                    }
                    return false;
}
            });
}
    }

    @Override
public final void inflateMenu(int resId) {
        xmlParser(resId);
        for (int i = 0; i < menuId.size(); i++) {
            showMenuPos.add(i);
}
        super.inflateMenu(resId);
}

    /**
     * 切換menu 輸入的引數是顯示的Menu檔案中的從上之下的postion
     *
     * @param posArry
*/
public final void initMenuView(int... posArry) {
        showMenuPos.clear();
        if (posArry != null && posArry.length > 0) {
            for (int i = 0; i < menuId.size(); i++) {
                for (int j = 0; j < posArry.length; j++) {
                    getMenu().findItem(menuId.get(i)).setVisible(false);
                    if (i == posArry[j]) {
                        getMenu().findItem(menuId.get(i)).setVisible(true);
showMenuPos.add(i);
                        break;
}
                }
            }
        }
    }

    /**
     * 解析menu檔案,獲取idList;
     *
     * @param resId
*/
private void xmlParser(int resId) {
        XmlResourceParser parser = getResources().getXml(resId);
        try {
            int event = parser.getEventType();
            while (event != XmlPullParser.END_DOCUMENT) {
                switch (event) {
                    case XmlPullParser.START_TAG:
                        int number = parser.getAttributeCount();
                        if (parser.getName().equals("item")) {
                            for (int i = 0; i < number; i++) {
                                if (parser.getAttributeName(i).equals("id")) {
                                    menuId.add(parser.getAttributeResourceValue(i, 0));
}
                            }
                        }
                        break;
                    default:
                        break;
}
                event = parser.next();
}
        } catch (XmlPullParserException e) {
            e.printStackTrace();
} catch (IOException e) {
            e.printStackTrace();
}
    }

    /**
     * 是否顯示系統的Title,配合AppBarLayout做動畫
     */
public void showNativeTitle() {
        String content = mContent.getText().toString().trim();
        if (content != null) {
            setTitle(content);
mContent.setVisibility(GONE);
}
    }


    @Override
public void setTitle(int resId) {
        super.setTitle(resId);
        if (mContent != null)
            mContent.setText(resId);
}

    @Override
public void setTitle(CharSequence title) {
        super.setTitle(title);
        if (mContent != null)
            mContent.setText(title);
}

    @Override
public void setTitleTextColor(int color) {
        super.setTitleTextColor(color);
        if (mContent != null)
            mContent.setTextColor(color);
}
}

在配合使用AppBarLayout的時候,配合呼叫showNativeTitle()方法就可以顯示自帶的Title了

好了,其他的更多功能可以增加的;