《一个Android工程的从零开始》-4、base(三) BaseActivity——Title

先扯两句

今天进入BaseActivity的第三部分——Title,这名字取的就顺嘴多了,想必大家从名字上也能看出来说的是什么,就不需要解释了,(虽然不想承认,其实是因为我懒),那么开始今天的内容吧。
还是想把我的码云地址分享给大家:

正文

想必有一部分人看完昨天的部分,会有一些疑问,那就是虽然经过昨天的内容,我们能够用Activity继承BaseActivity,并将对应的布局文件,显示到BaseActivity的title的下方,看起来却是省事了许多,可是title却是死的,如何去更改文本,控制按钮显示,或者说还有一些APP的首页,是不需要显示title的,这部分又如何操作呢。
下面就正是进入这部分,具体的也不乱说了,直接上方法。

设置标题:###

    /**
     * 设置标题
     * @param title 标题的文本
     */
    public void setTitle(String title) {
        TextView baseTitle = (TextView) findViewById(R.id.base_title);
        baseTitle.setText(title);
    }

还是绑定控件,然后设置标题,而标题的文本,则是通过方法传来的。
调用与上一篇中所说的类似,首先继承BaseActivity,然后调用setTitle方法,并写入参数即可。
代码如下:

public class MainActivity extends BaseActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setBaseContentView(R.layout.activity_main);
        setTitle("新Title");
    }
}

下面我们来看一下效果:
这张是原本的默认title的情况下:


这里写图片描述

设置了之后的效果:

这里写图片描述

这样就完成了Title的动态设置了。

返回按键###

下面我们再来看看左侧的返回键功能如何完成,其实这部分比title还要简单一些,因为这部分只需要在BaseActivity中做处理就可以了。
具体方法大家肯定都知道,先是在BaseActivity实现View.OnClickListener接口,在重写的onClick做id匹配,找到当点击的是返回时,调用finish(),代码如下(实现接口的部分想必大家都知道,就不贴了):

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.base_back:
                finish();
                break;

            default:
                break;
        }
    }

完成以上操作就可以实现退出了。
当然,也不是每一次我们都需要他点击了退出就立刻推掉的,例如编辑日记等,点击退出的时候,就需要做一个“是否放弃编辑”的提示,所以就需要额外加一些处理。
首先在BaseActivity中添加如下方法。

    public ImageView getBaseBack() {
        return (ImageView) findViewById(R.id.base_back);
    }

再回到MainActivity的onCreate方法中,添加如下代码:

getBaseBack().setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.i("log","退不出去了吧");
            }
});

这时再点击返回键的时候,就不会退出了,而是会在as的logcat面板中打印出“退不出去了吧”。而你想做什么操作,只要替换掉Log.i("log","退不出去了吧");,写自己的代码就好。
当然,或许会有人有疑惑,为什么这里需要重新new一个OnClickListener,BaseActivity已经实现了,那我们直接用getBaseBack().setOnClickListener(this);不就可以了吗?
这种方法我自然也尝试过,具体想了解的可以参见附录1。
当然,首页也有一些不需要返回键的,所以也单独写了一个方法,用来隐藏返回键。

    /**
     * 隐藏返回键
     */
    private void hideBack() {
        baseBack.setVisibility(View.GONE);
    }

功能按键###

除了以上这两种以外,title中余下的标题或者是文字我就统称为功能按键了。对于这些功能按键呢,我们需要的处理肯定更复杂,至于为什么,如果简单肯定不会放在最后说啊。
第一点:
相信分析一下,也确实如此,虽然我在第二篇博客中开始布局的时候,都使用了对应的图片,可是大家使用APP的时候肯定发现了,文字肯定不止是“确定”两个字,图片自然也不可能永远都是加号和更多(也就是横着排列的三个点)。
第二点:
再就是既然是按键,肯定也需要做点击事件,而且在不同的图片、不同的页面以及当前页面不同的状态,每个位置上的按键,所对应的点击事件也会不完全相同,所以按键的功能也需要我们做一下处理。
第三点:
也是在第二篇博客中,我就已经分析了这几个功能键可能出现的几种情况,什么都不显示啊、显示一个功能键啊、显示两个功能键。而对应每种情况,我们必然要设置谁显示,谁隐藏。

我重新缕清一下顺序,总结一下所需要处理的三个点(顺序有所调整)。

  1. 显隐
  2. 文本或者图片资源的切换
  3. 点击事件

分析好了,我们一个一个的来:

显隐

这部分最为简单,那就是将所有的功能控件的visibility都设置成gone,当需要调用哪个的时候,用java代码设置成View.VISIBLE就可以实现。

文本或者图片资源的切换

这部分内容呢,其实也比较简单,文本的就不用说了,参考一下title文本的设置部分即可,我们主要说一下图片(当然,主要说图片的主要原因还是因为图片的前面没有说罢了)。
这里所用的都是存在res目录下的图片资源,至于网络动态获取的部分,后面说到的时候,大家拿来用即可。
取id比较简单:

R.mipmap.more

就是res目录下的mipmap目录下的more图片,当然也有用drawable文件夹的(两个文件夹的区别我前面说过了,这里就不重复了)。
设置给ImageView设置图片的,好吧,也不复杂:

baseRightIcon1.setImageResource(resId);

baseRightIcon1就是ImageView,resId是传来的图片Id,所以这部分也搞定了。

点击事件

这里呢,其实也只需要两个部分:
一、设置点击监听,这个部分在BaseActivity的方法中完成

baseRightIcon1.setOnClickListener(this);

二、设置点击事件,这个部分在MainActivity(也就是要实现点击的活动类)中完成

    @Override
    public void onClick(View v) {
        super.onClick(v);
        switch (v.getId()) {
            case R.id.base_right_icon1:
                Log.i("Exception", "你点到我了");
                break;

            default:
                break;
        }
    }

下面贴出来完整的方法:
BaseActivity中的设置方法,

/**
     * 设置右侧图片1(最右侧)
     *
     * @param resId     图片的资源id
     * @param alertText 提示文本
     */
    public void setBaseRightIcon1(int resId, String alertText) {
        baseRightIcon1.setImageResource(resId);
        baseRightIcon1.setVisibility(View.VISIBLE);
        baseRightIcon1.setOnClickListener(this);
        //语音辅助提示的时候读取的信息
        baseRightIcon1.setContentDescription(alertText);
    }

MainActivity中的调用(在OnCreate中):

setBaseRightIcon1(R.mipmap.more, "更多");

好了以上就是今天的内容了吗?嗯,你个人勤快些的话,到这里就可以了,可是我这个人就是出奇的懒,每次都需要重写OnClick方法,而且还需要去记这几个功能键的id,别人我不知道,反正我个人是怕麻烦,所以想到了一个偷懒的方法。

接口的使用

看到题目想必大家也知道了,这部分要使用的内容就是接口了,不知大家是什么状态,反正我学java的时间内,最学不明白的就是接口,如今能把接口运用上,并且写到博客里,还是很有成就感的。
其实使用接口,我也比较无奈,实在是java不能像JavaScript一样,直接把方法做参数传递,不然又何必这么费事。接口的定义我就不多说了,毕竟从小就比较讨厌这些中看不中用的东西,我就直接上代码了。
在BaseActivity中做如下操作:
首先创建如下接口:

    public interface OnClickRightIcon1CallBack {
        void clickRightIcon1();
    }

里面就一个方法,因为接口中的方法会默认抽象,所以我就偷懒没有写。
随后创建一个私有的OnClickRightIcon1:

private OnClickRightIcon1CallBack onClickRightIcon1;

修改前面使用到的setBaseRightIcon1方法,添加一个参数OnClickRightIcon1CallBack onClickRightIcon1,并在其中添加一行代码:

this.onClickRightIcon1 = onClickRightIcon1;

修改后的setBaseRightIcon1长成这个样

    /**
     * 设置右侧图片1(最右侧)
     *
     * @param resId             图片的资源id
     * @param alertText         提示文本
     * @param onClickRightIcon1 点击处理接口
     */
    public void setBaseRightIcon1(int resId, String alertText, OnClickRightIcon1CallBack onClickRightIcon1) {
        this.onClickRightIcon1 = onClickRightIcon1;
        baseRightIcon1.setImageResource(resId);
        baseRightIcon1.setVisibility(View.VISIBLE);
        baseRightIcon1.setOnClickListener(this);
        //语音辅助提示的时候读取的信息
        baseRightIcon1.setContentDescription(alertText);
    }

最后一步,在OnClick中添加对应的id,并做点击处理。

@Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.base_back:
                finish();
                break;

            case R.id.base_right_icon1:
                onClickRightIcon1.clickRightIcon1();
                break;
                
            default:
                break;
        }
    }
    

如此操作下来,在子类中调用接口,就能点击操作了:

    setBaseRightIcon1(R.mipmap.more, "更多", new OnClickRightIcon1CallBack() {
            @Override
            public void clickRightIcon1() {
                Log.i("Exception","这都找到我了");
            }
    });

完整代码参见附录2

附录

附录1

我们如果按照设想的样子,直接用getBaseBack().setOnClickListener(this);,此时如果我们在MainActivity中重写OnClick方法处理返回事件的时候就会变成这个样子:

@Override
    public void onClick(View v) {
        super.onClick(v);
        switch (v.getId()) {
            case R.id.base_back:
                Log.i("log","退不出去了吧");
                break;

            default:
                break;
        }
    }

执行的结果,你当然也可以看到“退不出去了吧”的输出日志,可是同样你也会看到当前的Activity关闭了。
这是为什么呢,细心的会发现,这段代码多出了super.onClick(v);,也就是说在执行重新写的OnClick之前,需要先执行BaseActivity中的OnClick,所以自然就会两部分都执行到了。
当然或许还会有人说,那么既然找到问题了,我们注释掉super.onClick(v);不就可以了吗?
这样做自然是可以的,但是这里有一个前提,那就是我们BaseActivity的OnClick方法中不会有其他的点击事件处理,不然你注释掉这行代码后,其他的那些点击事件也不会有反应了。除非你能把使用到的每一个都重写。
还有一个点,就是每当你需要处理返回按钮的时候,都要想着将这行代码注释掉,不然就等着跟领导聊天吧。
所以如此的话,还不如简简单单重新new一个OnClickListener来得方便。

附录2

BaseActivity####

package com.mybaseapplication.base;

import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.ScrollView;
import android.widget.TextView;

import com.mybaseapplication.R;

import butterknife.ButterKnife;

public class BaseActivity extends AppCompatActivity implements View.OnClickListener {

    public Activity context;
    private ImageView baseBack, baseRightIcon2, baseRightIcon1;
    private TextView baseTitle, baseRightText;
    private OnClickRightIcon1CallBack onClickRightIcon1;
    private OnClickRightIcon2CallBack onClickRightIcon2;
    private OnClickRightTextCallBack onClickRightText;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_base);
        ButterKnife.inject(this);
        context = this;
        initView();
    }

    /**
     * 隐藏返回键
     */
    private void hideBack() {
        baseBack.setVisibility(View.GONE);
    }

    /**
     * 获取返回键
     */
    public ImageView getBackImage() {
        return baseBack;
    }

    /**
     * 初始化控件
     */
    private void initView() {
        baseRightIcon1 = (ImageView) findViewById(R.id.base_right_icon1);
        baseRightIcon2 = (ImageView) findViewById(R.id.base_right_icon2);
        baseBack = (ImageView) findViewById(R.id.base_back);
        baseTitle = (TextView) findViewById(R.id.base_title);
        baseRightText = (TextView) findViewById(R.id.base_right_text);
        baseBack.setOnClickListener(this);
    }

    /**
     * 设置标题
     *
     * @param title 标题的文本
     */
    public void setTitle(String title) {
        baseTitle.setText(title);
    }

    /**
     * 设置右侧图片1(最右侧)
     *
     * @param resId             图片的资源id
     * @param alertText         提示文本
     * @param onClickRightIcon1 点击处理接口
     */
    public void setBaseRightIcon1(int resId, String alertText, OnClickRightIcon1CallBack onClickRightIcon1) {
        this.onClickRightIcon1 = onClickRightIcon1;
        baseRightIcon1.setImageResource(resId);
        baseRightIcon1.setVisibility(View.VISIBLE);
        baseRightIcon1.setOnClickListener(this);
        //语音辅助提示的时候读取的信息
        baseRightIcon1.setContentDescription(alertText);
    }

    /**
     * 设置右侧图片2(右数第二个图片)
     *
     * @param resId     图片的资源id
     * @param alertText 提示文本
     */
    public void setBaseRightIcon2(int resId, String alertText, OnClickRightIcon2CallBack onClickRightIcon2) {
        this.onClickRightIcon2 = onClickRightIcon2;
        baseRightIcon2.setImageResource(resId);
        baseRightIcon2.setVisibility(View.VISIBLE);
        baseRightIcon2.setOnClickListener(this);
        //语音辅助提示的时候读取的信息
        baseRightIcon2.setContentDescription(alertText);
    }

    /**
     * 设置右侧文本信息
     *
     * @param text 所需要设置的文本
     */
    public void setBaseRightText(String text, OnClickRightTextCallBack onClickRightText) {
        this.onClickRightText = onClickRightText;
        baseRightText.setText(text);
        baseRightText.setVisibility(View.VISIBLE);
        baseRightText.setOnClickListener(this);
    }

    /**
     * 引用头部布局
     *
     * @param layoutId 布局id
     */
    public void setBaseContentView(int layoutId) {
        //当子布局高度值不足ScrollView时,用这个方法可以充满ScrollView,防止布局无法显示
        ((ScrollView) findViewById(R.id.base_scroll_view)).setFillViewport(true);
        LinearLayout layout = (LinearLayout) findViewById(R.id.base_main_layout);

        //获取布局,并在BaseActivity基础上显示
        final View view = getLayoutInflater().inflate(layoutId, null);
        //关闭键盘
        hideKeyBoard();
        //给EditText的父控件设置焦点,防止键盘自动弹出
        view.setFocusable(true);
        view.setFocusableInTouchMode(true);
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
        layout.addView(view, params);
    }

    /**
     * 隐藏键盘
     */
    public void hideKeyBoard() {
        View view = ((Activity) context).getWindow().peekDecorView();
        if (view != null) {
            InputMethodManager inputmanger = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
            inputmanger.hideSoftInputFromWindow(view.getWindowToken(), 0);
        }
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            //返回按键
            case R.id.base_back:
                finish();
                break;

            //图片1
            case R.id.base_right_icon1:
                onClickRightIcon1.clickRightIcon1();
                break;

            //图片2
            case R.id.base_right_icon2:
                onClickRightIcon2.clickRightIcon2();
                break;

            //右侧文本
            case R.id.base_right_text:
                onClickRightText.clickRightText();
                break;

            default:
                break;
        }
    }

    /**
     * 图片一点击回调接口
     */
    public interface OnClickRightIcon1CallBack {
        void clickRightIcon1();
    }

    public interface OnClickRightIcon2CallBack {
        void clickRightIcon2();
    }

    public interface OnClickRightTextCallBack {
        void clickRightText();
    }
}


MainActivity####

package com.mybaseapplication.ui.activity;

import android.os.Bundle;
import android.util.Log;
import android.view.View;

import com.mybaseapplication.R;
import com.mybaseapplication.base.BaseActivity;

public class MainActivity extends BaseActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setBaseContentView(R.layout.activity_main);
        //设置title文本
        setTitle("新Title");
        //设置返回拦截
        getBaseBack().setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.i("log","退不出去了吧");
            }
        });
        //设置功能键,以及点击方法回调监听
        setBaseRightIcon1(R.mipmap.more, "更多", new OnClickRightIcon1CallBack() {
            @Override
            public void clickRightIcon1() {
                Log.i("Exception","这都找到我了");
            }
        });
    }
}

附录3

《一个Android工程的从零开始》目录

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,718评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,683评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,207评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,755评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,862评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,050评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,136评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,882评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,330评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,651评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,789评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,477评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,135评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,864评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,099评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,598评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,697评论 2 351

推荐阅读更多精彩内容