Toolbar動態設定menu選單,標題居中,menu和返回鍵點選事件
阿新 • • 發佈:2019-02-20
最近用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=2)建立一個IToolbar繼承自Toolbar,並將view新增到IToolbar中"wrap_content" android:layout_gravity="center" tools:textColor="#fff" tools:text="123" xmlns:tools="http://schemas.android.com/tools" > </TextView>
private void initView() { View view = LayoutInflater.from(context).inflate(R.layout.itoolbar, this, false3)將mContent的值和Toolbar自帶的Title值,和顏色關聯起來就); mContent = view.findViewById(R.id.itoolbar_content); addView(view); setTitle("");//設定Toolbar自帶的標題為空 Toolbar.LayoutParams lp = (LayoutParams) view.getLayoutParams(); lp.gravity = Gravity.CENTER; this.setLayoutParams(lp); }
//這裡直接拿的系統的styleable TintTypedArray tta = TintTypedArray.obtainStyledAttributes4)在主佈局和Toolbar用法一樣,標題會居中顯示(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();
<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了
好了,其他的更多功能可以增加的;