Android开发小记

2018-07-04  本文已影响38人  忧郁的小码仔

1.闪屏页

在我们什么都不做之前,一个普通的android app启动的时候都会先显示一个黑/白屏(由应用的主题决定),这个是因为android在显示第一个Activity的页面之前会先去绘制窗体等等的一些操作。

一般情况下,我们会想直接在这个空档期显示一张图片,称之为闪屏页。这里我们用一个空的Activity作为启动页并给它设置一个主题用来显示一张图片:

        <activity android:name=".activity.FlushActivity"
                  android:screenOrientation="portrait"
            android:theme="@style/FlushTheme">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>

                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>

    <style name="FlushTheme" parent="AppTheme">
        <item name="android:windowBackground">@drawable/flush_page</item>
    </style>

之后,只需要在FlushActivity中做一个延时跳转即可:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        supportRequestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_flush);


        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                Intent intent = new Intent(FlushActivity.this, WorkOrderActivity.class);
                startActivity(intent);
                finish();
            }
        }, 3000);
    }

现在大家看到的app,大部分会在闪屏页展示一些广告,然后在某个小角落显示一个小小的跳过按钮或者倒计时按钮,如果是自己开发的app的话,我是肯定不会做这种设计的,每次使用一个新的app,如果它在闪屏页展示广告,这个app给我的印象就大大折扣了,即浪费了我的时间又浪费了我的心情。所以有的一些app更纯粹,根本就没有闪屏页,比如Google Play,知乎等等。

2.Activity切换动画

如果要给所有的Activity配置进入和退出动画,只需要在应用主题中配置相关的属性即可。

    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>

        <item name="android:windowAnimationStyle">@style/ActivityAnim</item>
    </style>
    <style name="ActivityAnim">
        <item name="android:activityOpenEnterAnimation">@anim/activity_in</item>
        <item name="android:activityCloseExitAnimation">@anim/activity_out</item>
        <item name="android:activityOpenExitAnimation">@anim/activity_no_anim</item>
        <item name="android:activityCloseEnterAnimation">@anim/activity_no_anim</item>
    </style>

这里的四个属性代表的意思如下:
android:activityOpenEnterAnimation:打开新的Activity并进入新的Activity时展示的动画
android:activityCloseExitAnimation:关闭当前Activity时展示的动画
android:activityOpenExitAnimation:打开新的Activity时,老的Activity消失时的动画
android:activityCloseEnterAnimation:关闭当前Activity,进入之前的Activity时展示的动画

activity_in.xml: (让Activity从屏幕的右侧滑入,一直到屏幕的左侧为止)

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromXDelta="100%"
    android:toXDelta="0"
    android:duration="300">

</translate>

activity_out.xml: (让Activity从屏幕左侧滑动到屏幕的右侧)

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromXDelta="0"
    android:toXDelta="100%"
    android:duration="300">

</translate>

activity_no_anim.xml: (无动画,这里主要是消除另一个Activity进入或退出时动画对当前Activity的影响。)

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromXDelta="0"
    android:toXDelta="0"
    android:duration="300">

</translate>

3.修改Toolbar上图片icon的宽高

想在toolbar上显示一个宽度112dp, 高44dp的图片按钮,一开始在menu.xml中定义了一个item,设置了icon, 但是显示出来的时候这个icon太小了,模糊不清。看到有人说这里给icon设置一个drawable, 将svg图片转换成xml, 然后在xml中修改宽高即可,我自己转了以下,也修改了对应的宽高,但是显示出来的效果很诡异,所以就放弃了,其实这里可以不通过menu.xml来设置,直接在toolbar中加一个ImageView控件即可:

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
        android:background="@color/colorPrimary">
        <ImageView
            android:id="@+id/img_qrorrfid"
            android:layout_gravity="end"
            android:layout_width="112dp"
            android:layout_height="44dp"
            android:scaleType="centerInside"
            android:src="@mipmap/scan_qr"/>
    </android.support.v7.widget.Toolbar>

4.dp和px转换

    public static int dp2px(Context context, float dpValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }

    public static int px2dp(Context context, float pxValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (pxValue/scale + 0.5f);
    }

5. Toast显示问题

如果连续几个Toast要显示的话,用户就要等Toast一个一个显示完,按照网上一些前辈的解决方法,可以这么写:

public class ToastUtils {

    private static Toast instance;

    public static void show(Context context, String message, int duration) {
        if (instance == null) {
            instance = Toast.makeText(context,message,duration);
        } else {
            instance.setText(message);
            instance.setDuration(duration);
        }
        instance.show();
    }

    public static void cancel() {
        if (instance != null) {
            instance.cancel();
        }
    }
}

这样,后来的Toast就可以直接覆盖之前的Toast了,用户也不用等所有的Toast一个一个显示了。注意,这里不要频繁的cancel(),会导致卡顿,在Activity销毁的时候调用cancel()就可以了。

6.AndroidManifest.xml 中自定义属性

有时候一些log或者其他的一些开关,丢到代码里老忘记打包的时候去修改,后边就想把所有的开关和配置都丢到AndroidManifest.xml里去得了。比如,开发时将网络请求参数等打印到log文件里,正式打包的时候就需要把它关掉。

AndroidManifest.xml<application>里加一个<meta-data>节点就可以了:

<application
        android:name=".MyApplication"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <!--**********打包时请注意修改*************-->
        <!--项目中用到的一些开关-->

        <meta-data android:name="com.test.logEnable" android:value="true"/>

        <!--项目中用到的一些开关-->
        <!--**********打包时请注意修改*************-->
    </application>

然后在MyApplication中去提供一个获取方法就可以了:

public class MyApplication extends Application {
    public static MyApplication shared;

    @Override
    public void onCreate() {
        super.onCreate();
        shared = this;
    }
    
    /*- 判断是否将log写入文件中 -*/
    public boolean isLogEnable() {

        boolean isLogEnable = false;
        ApplicationInfo applicationInfo;
        try {
            applicationInfo = MyApplication.this.getPackageManager()
                    .getApplicationInfo(MyApplication.this.getPackageName(), PackageManager.GET_META_DATA);
            isLogEnable = applicationInfo.metaData.getBoolean("com.test.logEnable");
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }

        return isLogEnable;
    }
}

然后在打log的工具类里,先去判断开关的状态再去执行就可以了:

public class LogUtils {


    public static void write(String message) {

        if (!MyApplication.shared.isLogEnable()) {
            return;
        }

        try {

            File logFile = new File(Environment.getExternalStorageDirectory().getPath() + "/myLog.log");
            String dateNow = DateFormatUtils.getString(new Date(), "yyyy-MM-dd HH:mm:ss");
            String log = "【" + dateNow + "】 >>>>" + message + "<<<<<<";

            FileWriter writer = new FileWriter(logFile,true);
            BufferedWriter bufferedWriter = new BufferedWriter(writer);
            bufferedWriter.write(log);
            bufferedWriter.newLine();
            bufferedWriter.newLine();
            bufferedWriter.flush();
            writer.close();
            bufferedWriter.close();

        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

这样,以后打包的时候只要关注AndroidManifest.xml文件就可以了。

上一篇下一篇

猜你喜欢

热点阅读