Android---EventBus3.0版本实现activity+fragment+fragment间的中英文切换

前言


在上一篇简书Android---EventBus3.0版本的使用及说明中,介绍了EventBus3.0的基础知识,并且也指出了如果在涉及activity,fragment间的通信时,可以优先的考虑使用EventBus。

结合项目中的需求,同时针对不同的用户群体,讲述如何利用EventBus实现Android APP的内部实现中英文切换的功能。先上效果图:

中英文切换.gif

一、准备工作


1. 添加依赖库

compile 'com.jakewharton:butterknife:8.8.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
compile 'org.greenrobot:eventbus:3.1.1'

特别推荐使用ButterKnife,非常好用,帮你省去很多findViewBy(R.id.*)的工作,而且搭配下图中的plugin--->Android ButterKnife Zelezny,简直不要太爽。关于Zelezny的用法,可以参考:ButterknifeZelezny在AndroidStudio中的配置与使用方法

image.png

2. 布局activity_main.xml
包含两个fragment和一个textview

<?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"
    tools:context="com.example.eventbus.MainActivity">

    <fragment
        android:name="com.example.eventbus.fragment.FirstFragment"
        android:id="@+id/fragment1"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"/>
    <fragment
        android:name="com.example.eventbus.fragment.SecondFragment"
        android:id="@+id/fragment2"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"/>
    <TextView
        android:id="@+id/main_text"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:gravity="center"
        android:text="@string/menu_text"/>
</LinearLayout>

3. 布局first_fragment.xml
很简单就一个按钮

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/colorPrimary">
    <Button
        android:id="@+id/btn1"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:text="@string/btn1"
        android:textColor="@color/colorAccent"/>
</LinearLayout>

4. 布局second_fragmeng.xml
也就几个简单的textview

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:background="@color/colorAccent">
    <TextView
        android:id="@+id/text1"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:text="@string/text1"
        android:background="#FFFDDD"
        android:textColor="@color/colorPrimaryDark"
        android:gravity="center"/>
    <TextView
        android:id="@+id/text2"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:text="@string/text2"
        android:background="#FFFDDD"
        android:textColor="@color/colorPrimaryDark"
        android:gravity="center"/>
    <TextView
        android:id="@+id/text3"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:text="@string/text3"
        android:background="#FFFDDD"
        android:textColor="@color/colorPrimaryDark"
        android:gravity="center"/>
    <TextView
        android:id="@+id/text4"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:text="@string/text4"
        android:background="#FFFDDD"
        android:textColor="@color/colorPrimaryDark"
        android:gravity="center"/>
</LinearLayout>

二、创建一个支持多语言切换功能的strings.xml


image.png
image.png
image.png
image.png

在按照图示建好后,需要向其中的strings.xml中输入内容,记住在默认的menu中输入的是:

<string name="menu_text">这是一个测试!</string>

而在strings.xml(en)中输入的是,相当于是中文的译文。

<string name="menu_text">This is a test!</string>

其他<string name=" ">类似。
在以上的准备工作完成后,开始正式的coding。


三、事件的建立


自定义一个事件类,根据需求可以是空类,也可以非空,根据需求,中英文的切换采用的是空类,仅作为一个事件的发送通知而已。

public class ChangeLanguageEvent {    
}

3.1 MainActivity

public class MainActivity extends AppCompatActivity {
    @BindView(R.id.main_text)
    TextView mainText;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);
        FragmentManager manager = getFragmentManager();
        FragmentTransaction transaction = manager.beginTransaction();

        FirstFragment fragment1 = new FirstFragment();
        SecondFragment fragment2 = new SecondFragment();

        transaction.add(R.id.fragment1, fragment1);
        transaction.add(R.id.fragment2, fragment2);
        transaction.commit();
    }

    /*个人建议在onResume注册EventBus
    *在可见可交互状态下注册,尽可能少的占用内存
    */
    @Override
    protected void onResume() {
        super.onResume();
        ButterKnife.bind(this);
        EventBus.getDefault().register(this);
    }

    /*个人建议在onPause注册EventBus(将当前Activity注册为事件订阅者) 
     *不影响功能的情况下提早解除注册,尽可能少的占用内存 
     */
    @Override
    protected void onPause() {
        super.onPause();
        EventBus.getDefault().unregister(this);
    }
    /**
     *用于实现内容的刷新,完成中英文的切换
     */
    @Subscribe
    public void refreshView(ChangeLanguageEvent event) {
        mainText.setText(getString(R.string.menu_text));
    }
}

代码很简洁,主要实现的功能是在activity中添加fragment,添加butterknife和eventbus的绑定和解绑。

重点来了,那么如何实现在fragment1中按下按钮,完成所有控件的中英文的切换呢?先上FirstFragment.class的代码:

public class FirstFragment extends Fragment {
    private static final String TAG = "AA";

    @BindView(R.id.btn1)
    Button btn1;

    private int checkedItem = 0;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//        super.onCreateView(inflater, container, savedInstanceState);
        View view = inflater.inflate(R.layout.first_fragment, container, false);
        ButterKnife.bind(this,view);
        EventBus.getDefault().register(this);
        return view;
    }

    @OnClick(R.id.btn1)
    public void onViewClicked() {
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        String[] language = {"中文","英文"};

        builder.setTitle(getString(R.string.btn1));
        builder.setSingleChoiceItems(language, checkedItem, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterface, int i) {
                checkedItem = i;
                Log.i(TAG, "onClick: i = " + i);
            }
        });
        builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int i) {
                dialog.dismiss();
                if (checkedItem == 0) {
                    updateLanguage(Locale.SIMPLIFIED_CHINESE);//切换中文
                    EventBus.getDefault().post(new ChangeLanguageEvent());
                } else {
                    updateLanguage(Locale.ENGLISH);//切换英文
                    EventBus.getDefault().post(new ChangeLanguageEvent());
                }
            }
        });
        builder.create().show();
    }

    private void updateLanguage(Locale locale){
        Resources resources = getResources();//获得res资源对象
        Configuration config = resources.getConfiguration();//获得设置对象
        DisplayMetrics dm = resources.getDisplayMetrics();//获得屏幕参数:主要是分辨率,像素等
        config.locale = locale;
        Log.i(TAG, "onClick: 当前语言:" + config.locale);
        resources.updateConfiguration(config,dm);
    }

    @Subscribe
    public void refreshView(ChangeLanguageEvent event){
        btn1.setText(getString(R.string.btn1));
    }
}

其中比较重要的是事件的发布,以及系统语言的设置:参考官网Android开发者官网中的Configuration:Configuration 包含了设备的所有的配置信息,这些配置信息会影响应用获取的资源。例如 string 资源,就是根据 Configuration 的 locale 属性来判断该取哪种语言的 string 资源,默认是 value 文件夹下的。因此语言的更新代码如下:

private void updateLanguage(Locale locale){
    Resources resources = getResources();//获得res资源对象
    Configuration config = resources.getConfiguration();//获得设置对象
    DisplayMetrics dm = resources.getDisplayMetrics();//获得屏幕参数:主要是分辨率,像素等
    config.locale = locale;
    Log.i(TAG, "onClick: 当前语言:" + config.locale);
    resources.updateConfiguration(config,dm);
}

事件的发布,根据不同的语言设定,将事件发布即可。

EventBus.getDefault().post(new ChangeLanguageEvent());

SecondFragment.class的代码直接如下:

public class SecondFragment extends Fragment {

    @BindView(R.id.text1)
    TextView text1;
    @BindView(R.id.text2)
    TextView text2;
    @BindView(R.id.text3)
    TextView text3;
    @BindView(R.id.text4)
    TextView text4;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//        super.onCreateView(inflater, container, savedInstanceState);
        View view = inflater.inflate(R.layout.second_fragment, container, false);
        ButterKnife.bind(this, view);
        EventBus.getDefault().register(this);
        return view;
    }

    @Subscribe(sticky = true)
    public void refreshView(ChangeLanguageEvent event){
        text1.setText(getString(R.string.text1));
        text2.setText(getString(R.string.text2));
        text3.setText(getString(R.string.text3));
        text4.setText(getString(R.string.text4));
    }
}

运行,测试即可得出如以上动态演示中的中英文切换的效果。


四、后续


本篇中讲述的中英文的切换仅仅是众多语言切换中的一种,用户可以根据需求,自行的设定 Locale 中的预设值。此外,此功能是与真机中的默认的语言有关系的,这里你可以自行根据示例代码验证。

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

推荐阅读更多精彩内容

  • 文|峰语 傍晚的天空乌云密布 我伸出手抓一把 撒上橄榄油 盐和黑胡椒 就着昨天剩下的吐司切片 作为晚餐 不太喜欢城...
    代峰语阅读 545评论 9 7
  • 15岁的夏天,空气软软的,舔一舔,有奶油糖的味道。蒙蒙细雨,将大地附着,细细密密。微风拂过,满满的,都是昨日你的暖...
    冰雨璇韵阅读 719评论 20 16