封装一个带toolbar的活动,toolbar只写一次


在最近的一个项目中,由于有多个活动要用到toolbar,所以一个一个编写的代价比较大。这里的思路是写一个含有toolbar的布局的活动,需要有toolbar的活动继承这个活动,然后将自己的布局文件装入toolbar下面的view。

来看布局文件的部分布局:

<android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="@drawable/backgroundcolor"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
            <TextView
                android:text="取消"
                android:visibility="invisible"
                android:id="@+id/tvLeft"
                android:textColor="#fff"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />
            <TextView
                android:id="@+id/title"
                android:layout_gravity="center"
                style="@style/TextAppearance.AppCompat.Widget.ActionBar.Title"
                android:text="cwncnsd"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content" />
        </android.support.v7.widget.Toolbar>
        <FrameLayout
            android:id="@+id/contentView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>


可以看到toolbar的下面有一个framelayout,也就是子活动要装入的布局:
LayoutInflater.from(ToolBarBaseActivity.this).inflate(getContentView(),contentView);

这样继承带来的问题就是灵活性的牺牲,子活动只能触碰这个framelayout,无法应对一些需求。比如需要侧滑菜单,需要在toolbar上左侧显示文字取消。所以要尽量把这个基类布局设计的完善,主要包括:

1.根布局使用drawerlayout,提供一个内容布局和一个侧滑菜单布局给子活动装入。

2.在toolbar上添加两个文本框,一个作为左侧可能显示的文本按钮(默认不显示),另一个是显示在中间的标题,使用系统定义的style。


这样布局文件就写完了,接下来看活动代码:

1.首先是onCreate:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_tool_bar_base);

        toolbar= (Toolbar) findViewById(R.id.toolbar);
        tv= (TextView) findViewById(R.id.title);
        tvLeft= (TextView) findViewById(R.id.tvLeft);
        setSupportActionBar(toolbar);
        getSupportActionBar().setDisplayShowTitleEnabled(false);//原默认标题不显示
        //将子活动的布局加载到内容布局中
        contentView= (FrameLayout) findViewById(R.id.contentView);
        LayoutInflater.from(ToolBarBaseActivity.this).inflate(getContentView(),contentView);
        //加载侧滑菜单
        sidemenu= (FrameLayout) findViewById(R.id.sidemenu);
        LayoutInflater.from(ToolBarBaseActivity.this).inflate(getSideMenu(),sidemenu);
        drawer= (DrawerLayout) findViewById(R.id.drawer);

        //给出初始化方法,传递缓存数据
        init(savedInstanceState);
    }
关于toolbar的初始化,禁用原标题,以及把两个布局文件装入内容布局和侧滑菜单,这里使用了两个抽象方法,直接返回布局文件ID,要求子类实现。还有就是定义抽象方法init,并传递onCreate的参数。


2.提供控制侧滑菜单的方法:

protected void openDrawer(){
        drawer.openDrawer(GravityCompat.END);
    }

protected void closeDrawer(){        drawer.closeDrawer(GravityCompat.END);    }

protected  void hideDrawer(){
        drawer.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);		//关闭手势滑动
    }
分别是开启菜单,关闭菜单和禁用菜单。有些活动用不到侧滑菜单,需要在初始化时禁用。


3.设置toolbar上的item:

toolbar的item分成两部分,左侧的navigation和右侧加载的一个item菜单。左侧的比较好设置:

protected  void setLeftButton(int buttonId, MyOnClickListener listener){
        this.leftlistener=listener;
        toolbar.setNavigationIcon(buttonId);
    }
监听不能在这里直接设置,所以自定义了一个监听接口并创建实例,在这里把参数传入实例,稍后会设置监听。

前面还提到了不用这个navigation而是用那个文本框,这个就比较简单了:

protected  void setLeftButton(String buttonText, View.OnClickListener listener){
        tvLeft.setVisibility(View.VISIBLE);
        tvLeft.setText(buttonText);
        tvLeft.setOnClickListener(listener);
    }


根据项目要求,我这里就认为右侧只显示一个按钮,所以设置右侧按钮就传入一个icon id和监听:

protected void setRightButton(int i,String s,MyOnClickListener rightlistener){
        this.rightId=i;
        this.rightTitle=s;
        this.rightlistener=rightlistener;
    }

接下来调用API进行真正的右侧图标设置:

先写一个菜单布局文件:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item android:id="@+id/item1"
        android:title=""
        app:showAsAction="always"/>
</menu>
很简单,就一个item。

接下来:

@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        if (rightId!= 0|| !TextUtils.isEmpty(rightTitle)){
            getMenuInflater().inflate(R.menu.toolbar_menu,menu);
        }
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        if (rightId!=0){
            menu.findItem(R.id.item1).setIcon(rightId);
        }
        if (!TextUtils.isEmpty(rightTitle)){
            menu.findItem(R.id.item1).setTitle(rightTitle);
        }
        return super.onPrepareOptionsMenu(menu);
    }
先判断rightId是否有,也就是用户是否设置,然后加载菜单。


设置监听:

@Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item.getItemId()==android.R.id.home){
            leftlistener.onClick();
        } else {
            rightlistener.onClick();
        }
        return true;//此事件已处理
    }
这个方法相当于toolbar的点击回调,左侧按钮的id是android.R.id.home,这个是固定的。点击时调用我们自定义的回调方法就可以了。


这样基本就写完了,其他的可以封装一下显示进度条什么的,

完整代码:

package com.example.a.app10.Activity;

import android.app.ProgressDialog;
import android.support.v4.view.GravityCompat;
import android.support.v4.view.ViewCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.example.a.app10.R;
import com.example.a.app10.tool.Net;

import q.rorbin.badgeview.QBadgeView;

public abstract class ToolBarBaseActivity extends AppCompatActivity {

    private Toolbar toolbar;
    private MyOnClickListener leftlistener,rightlistener;
    private int rightId;
    private String rightTitle;
    private FrameLayout contentView,sidemenu;
    private TextView tv;
    private DrawerLayout drawer;
    private ProgressDialog mProgressDialog;
    private TextView tvLeft;

    public interface MyOnClickListener{
        void onClick();
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_tool_bar_base);

        toolbar= (Toolbar) findViewById(R.id.toolbar);
        tv= (TextView) findViewById(R.id.title);
        tvLeft= (TextView) findViewById(R.id.tvLeft);
        setSupportActionBar(toolbar);
        getSupportActionBar().setDisplayShowTitleEnabled(false);//原默认标题不显示
        //将子活动的布局加载到内容布局中
        contentView= (FrameLayout) findViewById(R.id.contentView);
        LayoutInflater.from(ToolBarBaseActivity.this).inflate(getContentView(),contentView);
        //加载侧滑菜单
        sidemenu= (FrameLayout) findViewById(R.id.sidemenu);
        LayoutInflater.from(ToolBarBaseActivity.this).inflate(getSideMenu(),sidemenu);
        drawer= (DrawerLayout) findViewById(R.id.drawer);

        a();

        //给出初始化方法,传递缓存数据
        init(savedInstanceState);
    }

    protected abstract int getSideMenu();

    protected abstract void init(Bundle savedInstanceState);

    protected abstract int getContentView();

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item.getItemId()==android.R.id.home){
            leftlistener.onClick();
        } else {
            rightlistener.onClick();
        }
        return true;//此事件已处理
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        if (rightId!= 0|| !TextUtils.isEmpty(rightTitle)){
            getMenuInflater().inflate(R.menu.toolbar_menu,menu);
        }
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        if (rightId!=0){
            menu.findItem(R.id.item1).setIcon(rightId);
        }
        if (!TextUtils.isEmpty(rightTitle)){
            menu.findItem(R.id.item1).setTitle(rightTitle);
        }
        return super.onPrepareOptionsMenu(menu);
    }

    protected  void setLeftButton(int buttonId, MyOnClickListener listener){
        this.leftlistener=listener;
        toolbar.setNavigationIcon(buttonId);
    }

    protected  void setLeftButton(String buttonText, View.OnClickListener listener){
        tvLeft.setVisibility(View.VISIBLE);
        tvLeft.setText(buttonText);
        tvLeft.setOnClickListener(listener);
    }

    protected void setRightButton(int i,String s,MyOnClickListener rightlistener){
        this.rightId=i;
        this.rightTitle=s;
        this.rightlistener=rightlistener;
    }

    protected void setMyTitle(String i){
        tv.setText(i);
    }

    protected void openDrawer(){
        drawer.openDrawer(GravityCompat.END);
    }

    private void a() {
        Window window = getWindow();
        //设置透明状态栏,这样才能让 ContentView 向上
        window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);

    }

    //显示进度对话框
    protected void showProgress(String msg) {
        if (mProgressDialog == null) {
            mProgressDialog = new ProgressDialog(this);
            mProgressDialog.setCancelable(true);
        }
        mProgressDialog.setMessage(msg);
        mProgressDialog.show();
    }
    protected void hideProgress() {
        if (mProgressDialog != null) {
            mProgressDialog.dismiss();
        }
    }

    protected  void hideDrawer(){
        drawer.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED);		//关闭手势滑动
    }

    protected void closeDrawer(){
        drawer.closeDrawer(GravityCompat.END);
    }

}








  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值