您的位置:首页 > 其它

Toolbar动态设置menu菜单,标题居中,menu和返回键点击事件

2018-02-03 16:55 2006 查看
最近用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了

好了,其他的更多功能可以增加的;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息