android:系统Toast变身

本次对Toast的探索的原由是在做屏幕适配时改变了系统Density导致Toast变小了,上真相:
android:系统Toast变身_第1张图片
想到的最直观的解决方案就是能否把显示的文字的字号变大,ok打开源码看下是否提供了对应的Api。

//从Toast.makeText(MainActivity.this, "hide",Toast.LENGTH_LONG).show();跟入

public static Toast makeText(@NonNull Context context, @Nullable Looper looper,
            @NonNull CharSequence text, @Duration int duration) {
        Toast result = new Toast(context, looper);

        LayoutInflater inflate = (LayoutInflater)
                context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View v = inflate.inflate(com.android.internal.R.layout.transient_notification, null);
        TextView tv = (TextView)v.findViewById(com.android.internal.R.id.message);
        tv.setText(text);

        //注意这里!!!!!!
        result.mNextView = v;
        result.mDuration = duration;

        return result;
    }

很幸运第一眼就看到了Toast的布局文件,其中R.id.message就是显示文本的TextView,只不过是在源码中我们不能直接查看和修改,那有没有提供对应的Api呢?尴尬的是并没有发现,那我们就先看下Toast布局文件吧,Android在线源码,我们可以看到

<?xml version="1.0" encoding="utf-8"?>
<!--
/* //device/apps/common/res/layout/transient_notification.xml
**
** Copyright 2006, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
**     http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
-->

<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="?android:attr/toastFrameBackground">

    <TextView
        android:id="@android:id/message"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:layout_marginHorizontal="24dp"
        android:layout_marginVertical="15dp"
        android:layout_gravity="center_horizontal"
        android:textAppearance="@style/TextAppearance.Toast"
        android:textColor="@color/primary_text_default_material_light"
        />

</LinearLayout>

到这里我们对Toast的布局结构可以说是了如指掌了,JUST SO SO。我们如果能拿到这个view,问题就基本解决了。
再回到Toast源码发现了这个方法:

  /**
     * Return the view.
     * @see #setView
     */
    public View getView() {
        return mNextView;
    }

mNextView 就是Toast的view,到这解决方案已经相当明了了,直接开干上代码:

 public static void showToast(String str) {
        if (mContext == null) return;
        if (TextUtils.isEmpty(str)) return;
        if (mToast == null) {
            mToast = Toast.makeText(mContext, str, Toast.LENGTH_SHORT);
            LinearLayout ll= (LinearLayout) mToast.getView();
            TextView tv = (TextView) ll.getChildAt(0);
            tv.setTextSize(18); 
        } else {
            mToast.setText("时间管理大师:"+str);
        }
        mToast.show();
    }

验证一下:
android:系统Toast变身_第2张图片
ok,我们的思路是对的,诶…那么,我可以加个图标吗?当然!别说一个,一串也没问题,只要老板不打死你,至于布局样式就由大家自己去调吧

 public static void showToast(String str) {
        if (mContext == null) return;
        if (TextUtils.isEmpty(str)) return;
        if (mToast == null) {
            mToast = Toast.makeText(mContext, str, Toast.LENGTH_SHORT);
            LinearLayout ll= (LinearLayout) mToast.getView();
            //ll.removeAllViews();
            TextView tv = (TextView) ll.getChildAt(0);
            tv.setTextSize(18);
            ImageView iv = new ImageView(mContext);
            iv.setBackground(mContext.getDrawable(android.R.mipmap.sym_def_app_icon));
            ll.addView(iv);

        } else {
            mToast.setText("时间管理大师:"+str);
        }
        mToast.show();
    }

android:系统Toast变身_第3张图片还有一个与getView()对应的方法,你想要怎么显示布局,往里放就完了。

 /**
     * Set the view to show.
     * @see #getView
     */
    public void setView(View view) {
        mNextView = view;
    }

你可能感兴趣的:(android源码探索,android)