Android开发记录: 自定义组合控件,标题栏统一样式 提高效率(返回按钮、中间标题、菜单)

效果图

这里写图片描述

自定义控件

NormalAppbarLayout.java
import android.app.Activity;
import android.content.Context;
import android.support.annotation.MenuRes;
import android.support.design.widget.AppBarLayout;
import android.support.v7.widget.Toolbar;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;

import com.keihong.imapp.common.R;
import com.keihong.imapp.utils.ViewFinder;

import java.lang.ref.WeakReference;

/**
 * @author keihong.chan
 * @time 2018/5/3 下午2:53
 * @desc 自定义标题栏,统一样式(返回按钮、中间标题、菜单)
 * @others 自定义控件 组合模式 (AppbarLayout/toolbar + menu)
 */
public class NormalAppbarLayout extends AppBarLayout {


    private static WeakReference<Activity> mActivity;

    private View mRootLayout;
    private ViewFinder mVFinder;
    private TextView mTvTitle;
    private Toolbar mToolbar;

    private <T extends View> T findView(int resId) {
        return mVFinder.findView(resId);
    }

    public NormalAppbarLayout(Context context) {
        super(context);
    }

    public NormalAppbarLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        //在构造函数中,对标题栏布局进行动态加载
        //参数二 给加载好的布局再添加一个父布局 这里想要指定为NormalAppbarLayout,出入this
        mRootLayout = LayoutInflater.from(context).inflate(R.layout.lay_normal_appbar, this);
        mVFinder = new ViewFinder(mRootLayout);//查找控件的帮助类

        mTvTitle = findView(R.id.tv_title);
        mToolbar = findView(R.id.toolbar);
        mToolbar.setNavigationOnClickListener(new OnToolbarNavigationClickListener() {
        });//设置默认的Toolbar返回按钮事件
        //默认无菜单 所以不在构造函数中写菜单逻辑

    }

    /**
     * 初始化标题
     *
     * @param activity
     * @param title
     */
    public void init(Activity activity, String title) {
        mActivity = new WeakReference<>(activity);
        mTvTitle.setText(title);
    }

    /**
     * 为Toolbar设置菜单
     *
     * @param resId
     * @param onMenuItemClickListener
     */
    public void setMenu(@MenuRes int resId, Toolbar.OnMenuItemClickListener onMenuItemClickListener) {
        mToolbar.inflateMenu(resId);
        mToolbar.setOnMenuItemClickListener(onMenuItemClickListener);
    }

    /**
     * 为toobar的navigation设置点击事件
     *
     * @param listener
     */
    public void setNavigationClickListener(OnToolbarNavigationClickListener listener) {
        mToolbar.setNavigationOnClickListener(listener);

    }

    /**
     * 继承点击事件,封装常用逻辑
     * <p>
     * 把Activity finish封装进去
     */
    public static abstract class OnToolbarNavigationClickListener implements View.OnClickListener {

        @Override
        public void onClick(View v) {
            //默认 Toolbar 返回按钮是关闭Activity 可以覆写
            mActivity.get().finish();
        }
    }
}
lay_normal_appbar.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.AppBarLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/appbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="@dimen/actionBarSize"
        android:background="@color/colorPrimary"
        app:navigationIcon="@drawable/ic_arrow_back">

        <TextView
            android:id="@+id/tv_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:textAppearance="@style/Theme.ToolBar.Base.Title"
            tools:text="title" />

    </android.support.v7.widget.Toolbar>

</android.support.design.widget.AppBarLayout>
拓展

此代码忘记是哪位大神写的 若看到请告知
改用普通的findViewById或用ButteKnife也行

/**
 * Function:快速查找控件的帮助类
 */
public class ViewFinder
{
    private final String ERROR = "ViewFinder error: must set up layout !";
    private View mLayout;
    private SparseArray<View> mViews;

    public ViewFinder(View layout)
    {
        this.mLayout = layout;
        if (mLayout == null)
            throw new IllegalArgumentException(ERROR);
        this.mViews = new SparseArray<>();
    }

    /**
     * 获取布局
     */
    public View getLayout()
    {
        return mLayout;
    }

    /**
     * 通过控件的Id获取对于的控件,如果没有则加入views
     */
    public <T extends View> T findView(int viewId)
    {
        View view = mViews.get(viewId);
        if (view == null)
        {
            view = mLayout.findViewById(viewId);
            mViews.put(viewId, view);
        }
        return (T) view;
    }

    /**
     * 通过控件Id设置其对应的点击事件
     *
     * @param viewId   控件id
     * @param listener 点击事件
     * @return 该控件
     */
    public View addClick(int viewId, View.OnClickListener listener)
    {
        View view = findView(viewId);
        if (view != null)
            view.setOnClickListener(listener);
        return view;
    }

    /**
     * 设置控件点击事件
     *
     * @param view     控件对象
     * @param listener 点击事件
     * @return 该控件
     */
    public View addClick(View view, View.OnClickListener listener)
    {
        if (view != null)
            view.setOnClickListener(listener);
        return view;
    }
}

Usage

注释处为自定义toolbar navigation的点击事件

Activity or Fragment
... 

private void initAppbar() {
        mAppbarLayout.init(this, "我的远程指导预约情况");
//        mAppbarLayout.setNavigationClickListener(new NormalAppbarLayout.OnToolbarNavigationClickListener() {
//            @Override
//            public void onClick(View v) {
//                App.showToast("关闭啦哈哈哈", MyApplication.ToastType.SUCCESS);
//                super.onClick(v);
//            }
//        });
        mAppbarLayout.setMenu(R.menu.menu_plan_detail, new Toolbar.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(MenuItem item) {
                switch (item.getItemId()) {
                    case R.id.action_feedback:
                        App.showToast("知道啦", MyApplication.ToastType.SUCCESS);
                        break;
                    case R.id.action_download:
                        App.showToast("想得美", MyApplication.ToastType.SUCCESS);
                        break;
                }
                return true;
            }
        });
    }
layout xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <com.keihong.imapp.common.widget.NormalAppbarLayout
        android:id="@+id/appbar"
        android:layout_width="match_parent"
        android:layout_height="@dimen/actionBarSize" />

</LinearLayout>
menu文件就不给出了 懒
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

忘词木头人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值