實作Android導覽教學(fragment)
這次的案子是要把原有的app增加一個新手導覽教學的功能
但是不是整頁換頁的方式(像是用setContent把整頁內容改變),而是以原本存在的頁面上面蓋上一層透明的頁面,然後導覽使用者點下按鈕之後才會繼續下一步。
全部的導覽結束之後,這個透明的頁面會消失,然後恢復原本的使用介面。
大概長得像是這樣:
需要用到的主要概念有三個:
1. 使用不揮發變數(SharedPreference)來設立一個初始值為false的flag,讓教學導覽結束之後把flag調回true,以免使用者下次打開之後又開始教學導覽
2. 調整style.xml檔案,用AndroidManifest.xml指定activity後用setContent鋪上透明主題頁面
3. fragment的增加,覆蓋,以及在最後結束時關閉透明頁面
(如果你是想要跟上圖一樣只有這樣一個介面,按下螢幕之後就結束的話,可能不需要fragment)
--- 1. 不揮發變數 ---
放一個flag的變數進去SharedPreference
關於存取權限:
MODE_PRIVATE 只允許本應用程式內存取。
MODE_MULTI_PROCESS 允許多個行程同時存取,在Android 2.3(含)以前的版本都是預設開啟,但2.3之後要指定這個參數才允許多行程同時存取。
MODE_WORLD_READABLE 讓手機中的所有app都能讀取,因為風險性太高,從API 17版開始就不建議使用了。
如何改變該值:
如何取出該值:
--- 2. 透明頁面 ---
在style.xml下面多寫一個主題,讓背景變灰階透明
然後在layout資料夾下做一個什麼都沒有的空白頁面,ID命名為transparentpage.xml
然後在AndroidManifest.xml下面找到寫有application的框框內
多下這一行
這樣子設定主要是讓你的activity下的setContent可以改變主題
然後
如果之後要關閉這個透明頁面的話就寫個
但是!只有這樣寫的話,在關閉這個頁面的時候會有一個很多餘的滑出動畫,讓整個畫面結束的感覺有點LOW。
這時候多加一個
這樣就不會有一個滑出動畫了。
掰惹位,有些使用者可能會手滑按到後退鍵結果導致整個導覽消失。
多加這個防止他們按到:
--- 3.Fragment --
有時候會有需求要在透明的頁面上加圖案或者加按鈕什麼的
這時候就要再新增一個layout,用fragment的方法來加上去
首先先做個fragment的java檔
然後在Activity內下一個replace的指令就可以蓋上去了。
補充:
當然一個fragment也不會只有蓋上去這個方法,往上疊加或者去掉最前面的fragment也是都可以做得到的,但是一定要考慮到Android的生命週期。可以參考這個網站有詳細的解說。
直接把重點節錄下來就是:
FragmentTransaction有一些基本方法,下面給出調用這些方法時,Fragment生命週期的變化:
* add(): onAttach()->…->onResume()。
* remove(): onPause()->…->onDetach()。
* replace(): 相當於舊Fragment調用remove(),新Fragment調用add()。
* show(): 不調用任何生命週期方法,調用該方法的前提是要顯示的Fragment已經被添加到容器,只是純粹把Fragment UI的setVisibility為true。
* hide(): 不調用任何生命週期方法,調用該方法的前提是要顯示的Fragment已經被添加到容器,只是純粹把Fragment UI的setVisibility為false。
* detach(): onPause()->onStop()->onDestroyView()。UI從佈局中移除,但是仍然被FragmentManager管理。 * attach(): onCreateView()->onStart()->onResume()。
抱歉這次沒辦法提供程式碼,而且必須要刪掉一些公司用的東西,很有可能會漏掉一小部分,如果有問題可以留言。我會再補上來。
大概長得像是這樣:
需要用到的主要概念有三個:
1. 使用不揮發變數(SharedPreference)來設立一個初始值為false的flag,讓教學導覽結束之後把flag調回true,以免使用者下次打開之後又開始教學導覽
2. 調整style.xml檔案,用AndroidManifest.xml指定activity後用setContent鋪上透明主題頁面
3. fragment的增加,覆蓋,以及在最後結束時關閉透明頁面
(如果你是想要跟上圖一樣只有這樣一個介面,按下螢幕之後就結束的話,可能不需要fragment)
--- 1. 不揮發變數 ---
放一個flag的變數進去SharedPreference
SharedPreferences sharedPreferences = getSharedPreferences("flag" , MODE_PRIVATE); //取得SharedPreferences , 丟入的參數為("名稱" , 存取權限)
關於存取權限:
MODE_PRIVATE 只允許本應用程式內存取。
MODE_MULTI_PROCESS 允許多個行程同時存取,在Android 2.3(含)以前的版本都是預設開啟,但2.3之後要指定這個參數才允許多行程同時存取。
MODE_WORLD_READABLE 讓手機中的所有app都能讀取,因為風險性太高,從API 17版開始就不建議使用了。
如何改變該值:
sharedPreferences.edit().putboolean("flag" , false).apply(); //存入資料,丟入的參數為(key , value)
如何取出該值:
sharedPreferences.getboolean("flag" , false); //取出資料, 丟入的參數為(key , 若是沒值,預設為多少)
--- 2. 透明頁面 ---
在style.xml下面多寫一個主題,讓背景變灰階透明
<drawable name="transparameter">#7f000000</drawable> <style name="Theme.TranslucentBackground" parent="AppTheme"> <item name="android:windowBackground">@drawable/transparameter</item> <item name="android:colorBackgroundCacheHint">@null</item> <item name="android:windowIsTranslucent">true</item> <item name="android:windowNoTitle">true</item> </style>
然後在layout資料夾下做一個什麼都沒有的空白頁面,ID命名為transparentpage.xml
然後在AndroidManifest.xml下面找到寫有application的框框內
多下這一行
<activity android:name="你要執行setContent的Activity路徑" android:hardwareAccelerated="false" android:screenOrientation="portrait" android:configChanges = "fontScale" android:theme="@style/Theme.TranslucentBackground" />
這樣子設定主要是讓你的activity下的setContent可以改變主題
然後
setContentView(R.layout.tutorial_transparentpage);就可以鋪上一個透明頁面了~
如果之後要關閉這個透明頁面的話就寫個
finish();就可以了。
但是!只有這樣寫的話,在關閉這個頁面的時候會有一個很多餘的滑出動畫,讓整個畫面結束的感覺有點LOW。
這時候多加一個
public void finish(){ //cancel the animation when finish activity super.finish(); overridePendingTransition(0,0); }
這樣就不會有一個滑出動畫了。
掰惹位,有些使用者可能會手滑按到後退鍵結果導致整個導覽消失。
多加這個防止他們按到:
//backKey無效 @Override public boolean dispatchKeyEvent(KeyEvent event) { if (event.getAction()==KeyEvent.ACTION_DOWN) { switch (event.getKeyCode()) { case KeyEvent.KEYCODE_BACK: return true; } } return super.dispatchKeyEvent(event); }
--- 3.Fragment --
有時候會有需求要在透明的頁面上加圖案或者加按鈕什麼的
這時候就要再新增一個layout,用fragment的方法來加上去
首先先做個fragment的java檔
public class TutorialFragment extends Fragment{ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { super.onCreateView(inflater,container,savedInstanceState); return inflater.inflate(要蓋上去的新layout, container, false); } }
然後在Activity內下一個replace的指令就可以蓋上去了。
private FragmentManager fragmentManager; private Fragment fragment = new Fragment(); fragment = new TutorialFragment(); FragmentTransaction transaction = fragmentManager.beginTransaction(); transaction.replace(containerViewIdint,fragment); transaction.addToBackStack(null); transaction.commit();
補充:
當然一個fragment也不會只有蓋上去這個方法,往上疊加或者去掉最前面的fragment也是都可以做得到的,但是一定要考慮到Android的生命週期。可以參考這個網站有詳細的解說。
直接把重點節錄下來就是:
FragmentTransaction有一些基本方法,下面給出調用這些方法時,Fragment生命週期的變化:
* add(): onAttach()->…->onResume()。
* remove(): onPause()->…->onDetach()。
* replace(): 相當於舊Fragment調用remove(),新Fragment調用add()。
* show(): 不調用任何生命週期方法,調用該方法的前提是要顯示的Fragment已經被添加到容器,只是純粹把Fragment UI的setVisibility為true。
* hide(): 不調用任何生命週期方法,調用該方法的前提是要顯示的Fragment已經被添加到容器,只是純粹把Fragment UI的setVisibility為false。
* detach(): onPause()->onStop()->onDestroyView()。UI從佈局中移除,但是仍然被FragmentManager管理。 * attach(): onCreateView()->onStart()->onResume()。
抱歉這次沒辦法提供程式碼,而且必須要刪掉一些公司用的東西,很有可能會漏掉一小部分,如果有問題可以留言。我會再補上來。
留言
張貼留言