1. 程式人生 > >Android實現過渡動畫、引導頁 Android判斷是否第一次啟動App

Android實現過渡動畫、引導頁 Android判斷是否第一次啟動App

最近參加比賽聯絡模擬題其中有一道題是:


結合上學期期末實訓整理的資料,加上網上博主的博文參考。再次整理一遍,以供以後參考。

這篇是基於Android自身的控制元件View做出的效果。

文章最後附上利用RXJAVA技術做成的引導頁。

首先是過渡動畫,因為它不論App是否第一次啟動都會顯示。

這裡我使用了Handler的postDelayed()方法。把過渡動畫的Activity設為預設啟動的Activity。在當前Activity中,執行postDelayed()方法,把延時的時長設為兩秒即可。

過渡頁面如下:transition_view.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:orientation="vertical"
    android:background="#fff"
    >

    <ImageView
        android:src="@drawable/profile"
        android:layout_marginTop="80dp"
        android:layout_gravity="center"
        android:layout_width="100dp"
        android:layout_height="100dp" />

</LinearLayout>


這裡因為我的圖片背景是白色的,就沒有設定LinearLayout的背景色了,如果Logo的背景色不一樣,則可以進行設定。也可以直接用ImageView解決。

過渡Activity如下:TransitionActivity.java

?
package com.ikok.transitionandguidingpage;

import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.Handler;
import android.view.Window;

/**
 * Created by Anonymous on 2016/3/25.
 */
public class TransitionActivity extends Activity {

    boolean isFirstIn = false;
    private Intent intent;

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

        final SharedPreferences sharedPreferences = getSharedPreferences("is_first_in_data",MODE_PRIVATE);
        isFirstIn = sharedPreferences.getBoolean("isFirstIn",true);
        new Handler().postDelayed(new Runnable() {

            @Override
            public void run() {
                if (isFirstIn) {
//                    Toast.makeText(TransitionActivity.this, "First log", Toast.LENGTH_SHORT).show();
                    intent = new Intent(TransitionActivity.this, GuideActivity.class);
                    TransitionActivity.this.startActivity(intent);
                    TransitionActivity.this.finish();
                } else {
                    intent = new Intent(TransitionActivity.this, MainActivity.class);
                    TransitionActivity.this.startActivity(intent);
                    TransitionActivity.this.finish();
                }
            }
        }, 2000);

    }

}

顯示了過渡動畫後,則需要判斷是否是第一次啟動App了。因為根據是否是第一次啟動App會判斷進入引導頁還是主頁。
因為這個判斷並不是一次執行就不需再執行了,而是每次啟動App的時候都需要進行判斷。所以這個判斷的資料需要持久化。

且為了判斷的時間很短,就不需要進行訪問資料庫,或者網路訪問等耗時操作了。直接使用 SharedPreferences  進行處理。

首先去指定 SharedPreferences  檔案的名稱,如果不存在則會建立一個。建立的檔案存放在 /data/data/<package name>/shared_prefs/ 目錄下。

第二個引數是指定對該檔案的操作模式。預設是 MODE_PRIVATE ,和直接傳入0是一樣的,表示只有當前程式才能對這個檔案進行讀寫操作。

MODE_MULTI_PROCESS 是用於多個程式對同一個 SharedPreferences  檔案進行讀寫操作。

建立好了檔案,接下來我們讀取標誌,看程式是否是第一次啟動App。

getBoolean("isFirstIn",true); 這個是用來獲取標誌的,它是用來取出檔案中對應的鍵值對。第一個引數是鍵,第二個引數是預設值。

它會取出對應鍵的值,如果沒有這個鍵,或者沒有值,則直接使用預設值,即第二個引數。因為我建立SharedPreferences  檔案的時候並沒有建立這個鍵值對。

所以,它是讀不出對應的鍵的值的,則會直接獲取到 true 值。則App判斷為第一次啟動。接下來使用Intent,根據值,則開啟了引導頁即 GuideActivity 。

引導頁 頁面如下:guide_view.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.support.v4.view.ViewPager
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

    </android.support.v4.view.ViewPager>

</LinearLayout>

這裡是v4包下的ViewPager。引導頁我決定使用ViewPager+FragmentPagerAdapter來實現。
如果我直接通過判斷VIewPager是否是最後一頁,再左滑進入App主頁,ViewPager切換到主頁時候會有一點問題。可能左滑了一點,但是還想看前兩張引導頁,再右滑,
結果是直接進入了App主頁,而不是上一張。體驗感很不好,所以考慮到最後一頁上有一個按鈕,來進行點選進入App主頁。這樣體驗感會好一點。

引導頁Activity如下:GuideAcitivity.java

?
package com.ikok.transitionandguidingpage;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.Window;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by Anonymous on 2016/3/26.
 */
public class GuideActivity extends FragmentActivity {

    private ViewPager mViewPager;
    private FragmentPagerAdapter mAdapter;
    private List<Fragment> mFragment = new ArrayList<Fragment>();

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

        mViewPager = (ViewPager) findViewById(R.id.viewpager);

        Fragment guide1 = new Guide1();
        Fragment guide2 = new Guide2();
        Fragment guide3 = new Guide3();

        mFragment.add(guide1);
        mFragment.add(guide2);
        mFragment.add(guide3);

        mAdapter = new FragmentPagerAdapter(getSupportFragmentManager()) {
            @Override
            public Fragment getItem(int position) {
                return mFragment.get(position);
            }

            @Override
            public int getCount() {
                return mFragment.size();
            }
        };

        // 為ViewPager新增動畫效果,3.0以上可用
        mViewPager.setPageTransformer(true,new DepthPageTransformer());
//        mViewPager.setPageTransformer(true,new ZoomOutPageTransformer());
        mViewPager.setAdapter(mAdapter);

    }
}


中間建立了三個Fragment,去載入佈局,佈局就是在xml的根節點上添加了 background 屬性。

這裡我為ViewPager的切換添加了切換動畫。使用的 Google 官方文件上列出的兩種動畫效果。

當然可以進行自定義切換動畫,我本來自定義了一個切換20度角的切換動畫,但覺得不是很好看就沒放上來了。

切換動畫,低版本不支援。又添加了 nineoldandroid ,來使動畫相容到低版本。

最後一個頁面如下:guide_view3.xml

?
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:background="@drawable/guide3" 
    android:layout_height="match_parent">

    <Button
        android:id="@+id/into_app_btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="進入App"
        android:textColor="#fefefe"
        android:background="@drawable/button_shape"
        android:layout_alignParentBottom="true"
        android:layout_centerInParent="true"
        android:layout_marginBottom="50dp"
        />

</RelativeLayout>


第三頁的程式碼如下: Guide3.java

?
package com.ikok.transitionandguidingpage;

import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;

/**
 * Created by Anonymous on 2016/3/27.
 */
public class Guide3 extends Fragment {

    private Button mIntoAppBtn;
    private View view;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        view = inflater.inflate(R.layout.guide_view3,container,false);
        return view;
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        mIntoAppBtn = (Button) view.findViewById(R.id.into_app_btn);
        mIntoAppBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(getActivity(), MainActivity.class);
                startActivity(intent);

                SharedPreferences sharedPreferences = getActivity().getSharedPreferences("is_first_in_data", 0x0000);
                SharedPreferences.Editor editor = sharedPreferences.edit();
                editor.putBoolean("isFirstIn", false);
                editor.commit();

                getActivity().finish();
            }
        });
    }
}

這裡我就對頁面上的Button綁定了一個點選事件監聽器。點選進入主頁,並且修改判斷是否第一次進入App的標誌值。
通過 SharedPreferences.Editor 物件去修改標誌值。然後 commit ,沒有 commit 是沒有進行更新儲存的。

這裡getSharedPreferences() 的第二個引數,我直接使用了 0x0000,十六進位制的0。

因為當時我使用 MODE_PRIVATE 的時候報錯,然後我就通過查原始碼,發現 MODE_PRIVATE 的值就是 0x0000,所以我直接使用了這個 0x0000。

為什麼報錯呢?因為 MODE_PRIVATE 是Context 裡的變數,在 Fragment 裡無法識別。如果一定要用,則使用 Context.MODE_PRIVATE。

為什麼 Activity 能用呢?因為 Activity 繼承了 Context, 而 Fragment 沒有繼承 Context。

本來我做的是在主頁的Activity中去修改這個標誌值。但是後面考慮到,如果不是第一次啟動,每次進入到主頁,都需要修改一次標誌值,即使它沒有變化,還是多做了很多無用功。所以在最後一頁的點選事件裡進行修改。標誌值只需要修改一次,引導頁也只出現一次,正好。

主頁就是建立工程預設的主頁了。

其他事項:

給Button加了樣式屬性。
button_shape.xml

?
<?xml version="1.0" encoding="utf-8"?>
<shape
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <!-- 填充的顏色 -->
    <solid android:color="#00FFFFFF" />
    <stroke android:color="#fefefe"
            android:width="1dp"
        />
    <!-- 設定按鈕的四個角為弧形 -->
    <!-- android:radius 弧形的半徑 -->
    <corners android:radius="5dip" />

    <!-- padding:Button裡面的文字與Button邊界的間隔 -->
    <padding
        android:left="10dp"
        android:top="10dp"
        android:right="10dp"
        android:bottom="10dp"
        />
</shape>

進入程式會出現一瞬間的空白,然後顯示正常。這是因為AppTheme。這裡我新建了一個空的樣式。然後讓預設啟動的Activity去應用空的樣式。
style.xml

?
<pre name="code" class="html"><resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- 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="EmptyTheme">

    </style>

</resources>

AndroidManifest.xml

?
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.ikok.transitionandguidingpage">

    <application
        android:allowBackup="true"
        android:icon="@drawable/profile"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">

        </activity>
        <!--應用空樣式-->
        <activity android:name=".TransitionActivity"
                    android:theme="@style/EmptyTheme">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".GuideActivity">

        </activity>
    </application>

</manifest>

以上就是本文的全部內容,希望對大家的學習有所幫助。


利用RxJava 技術做成的Android應用引導頁地址:https://blog.csdn.net/sinat_38239454/article/details/79876832