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了

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值