2. 歡迎模組
上一節對整個專案進行了綜述(可參見1. 專案綜述 進行了解),接下來將從歡迎模組開始詳細介紹。
知識點:
- 掌握歡迎介面的開發
- 主介面的標題欄
- 底部導航欄模組的開發,能夠搭建底部導航欄
1. 歡迎介面
任務綜述:
在實際開發中,開啟應用程式時首先會呈現一個歡迎介面。此介面主要用於展示產品LOGO和公司的新聞資訊。
1.1 歡迎介面
任務實施:
(1)建立專案。
指定包名為com.XXXX.newsdemo 。
(2)匯入介面圖片。
切換到Project選項卡/res中建立一個drawable-hdpi資料夾/匯入背景圖片;專案的icon圖示匯入mipmap-hdpi資料夾。
(3)建立歡迎介面。
類名為SplashActivity,佈局檔名activity_splash。
activity_splash.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/launch_bg" > </RelativeLayout>
(4)新增一個無標題的樣式。專案建立時所有介面預設的藍色標題欄不夠美觀。
styles.xml
<style name="AppTheme.NoActionBar"> <item name="windowActionBar">false</item> <item name="windowNoTitle">true</item> </style>
(5)修改清單檔案。專案需要設定自己的圖示與無標題欄的樣式,因此需要修改清單檔案中<application>標籤中的icon與theme屬性。
android:icon="@mipmap/app_icon" android:theme="@style/AppTheme.NoActionBar"
注意:
由於SplashActivity為程式的啟動介面,因此需要在清單檔案中設定啟動介面對應的Activity為SplashActivity。
1.2 歡迎介面邏輯程式碼
任務分析:
歡迎介面主要展示產品LOGO與新聞資訊,通常會在該介面停留一段時間後自動跳轉到其他介面,因此需要在邏輯程式碼中設定歡迎介面暫停幾秒(3秒)後再跳轉。
任務實施:
建立init()方法,在該方法中使用Timer和TimerTask類設定歡迎介面延遲3s再跳轉到主介面(MainActivity,此時為空白介面)。
SplashActivity.xml
public class SplashActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_splash); init(); } private void init() { //利用Timer讓此介面延遲3秒後再跳轉,timer中有一個執行緒,這個執行緒不斷執行task Timer timer = new Timer(); //timertask實現runnable介面,TimerTask類表示一個在指定時間內執行的task TimerTask task = new TimerTask() { @Override public void run() { Intent intent = new Intent(SplashActivity.this, MainActivity.class); startActivity(intent); SplashActivity.this.finish(); } }; timer.schedule(task, 3000); //設定這個task在延遲三秒之後自動執行 } }
2. 導航欄
任務綜述:
專案中有一個底部導航欄,底部導航欄主要用於滑動切換不同的介面或者點選底部按鈕時切換不同的介面,使使用者操作比較方便便捷。
2.1 標題欄
任務分析:
在專案中都有一個“後退”鍵和一個標題。為了便於程式碼重複使用可以將“後退”鍵和標題抽取出來並單獨放在一個佈局檔案(main_title_bar.xml)中。

標題欄介面
(1) 建立標題欄介面。
2個TextView:分別用於顯示後退鍵(樣式採用背景選擇器的方式)和當前介面標題(介面標題暫未設定,需要在程式碼中動態設定),並設定標題欄背景透明。
main_title_bar.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/title_bar" android:layout_width="match_parent" android:layout_height="45dp" android:background="@android:color/transparent"> <TextView android:id="@+id/tv_back" android:layout_width="45dp" android:layout_height="45dp" android:layout_alignParentLeft="true" android:layout_centerVertical="true" android:background="@drawable/go_back_selector" android:visibility="gone" /> <TextView android:id="@+id/tv_main_title" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:textColor="@android:color/white" android:textSize="18sp" /> </RelativeLayout>
(2)建立背景選擇器。標題欄介面中的返回鍵在按下(顯示灰色圖片)與彈起(顯示白色圖片)的狀態切換它的背景圖片,給使用者帶來動態效果。
go_back_selector.xml
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/iv_back_selected" android:state_pressed="true"/> <item android:drawable="@drawable/iv_back"/> </selector>
2.2 底部導航欄
任務分析:
此專案包含一個底部導航欄(即底部4個按鈕),為了方便後續佈局的搭建,建立一個底部導航欄UI的框架。
任務實施:
(1)匯入介面圖片(8張圖)。
(2)放置介面佈局。
在activity_main.xml中,通過<include>標籤main_title_bar.xml(標題欄)引入。其中4個RadioButton控制元件用於顯示底部按鈕,1個ViewPager控制元件使用者在載入每個底部按鈕對應的介面後可以左右滑動。
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <include layout="@layout/main_title_bar"/> <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent"> <RadioGroup android:id="@+id/radioGroup" android:layout_width="match_parent" android:layout_height="50dp" android:layout_alignParentBottom="true" android:background="@android:color/white" android:orientation="horizontal"> <RadioButton android:id="@+id/rb_home" style="@style/style_RadioButton" android:checked="true" android:drawableTop="@drawable/rb_home_selector" android:text="首頁" android:textColor="@drawable/rb_text_selector" /> <RadioButton android:id="@+id/rb_count" style="@style/style_RadioButton" android:drawableTop="@drawable/rb_count_selector" android:text="統計" android:textColor="@drawable/rb_text_selector" /> <RadioButton android:id="@+id/rb_video" style="@style/style_RadioButton" android:drawableTop="@drawable/rb_video_selector" android:text="視訊" android:textColor="@drawable/rb_text_selector" /> <RadioButton android:id="@+id/rb_me" style="@style/style_RadioButton" android:drawableTop="@drawable/rb_me_selector" android:text="我" android:textColor="@drawable/rb_text_selector" /> </RadioGroup> <android.support.v4.view.ViewPager android:id="@+id/viewPager" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_above="@id/radioGroup" /> </RelativeLayout> </LinearLayout>
(3)建立背景選擇器。根據按鈕被選中和未被選中的狀態切換它的背景圖片,給使用者帶來動態效果。當按鈕未被選中時顯示灰色圖片,被選中時顯示紅色圖片,以此類推其他3個背景選擇器rb_count_selector.xml,rb_video_selector.xml,rb_me_selector.xml。
rb_home_selector.xml
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android" > <item android:state_checked="true" android:drawable="@drawable/home_press"/> <item android:state_checked="false" android:drawable="@drawable/home_normal"/> </selector>
(4)建立文字顏色選擇器。底部導航欄介面中的底部按鈕所對應的文字顏色在按鈕被選中與未被選中時也會有變化,因此同樣需要建立一個背景選擇器用於控制文字顏色,當按鈕未被選中時文字顏色為灰色,當被選中時文字顏色為紅色。
rb_text_selector.xml
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android" > <item android:state_checked="true" android:color="@color/rdTextColorPress"/> <item android:state_checked="false" android:color="@color/rdTextColorNormal"/> </selector>
上訴檔案中的rdTextColorPress、TextColorNormal兩個顏色值寫在colors.xml檔案中,便於以後多次使用。
<color name="rdTextColorNormal">#999999</color> <color name="rdTextColorPress">#eb413d</color>
(5)建立底部按鈕的樣式。由於底部導航欄的4個按鈕具有相同的外觀,因此需要為這4個按鈕建立一個相同的樣式,用於設定按鈕的寬度、高度、比值、位置以及文字的大小。
styles.xml
<style name="style_RadioButton"> <item name="android:layout_width">match_parent</item> <item name="android:layout_height">wrap_content</item> <item name="android:button">@null</item> <item name="android:background">@null</item> <item name="android:layout_weight">1</item> <item name="android:gravity">center</item> <item name="android:layout_gravity">center</item> <item name="android:textSize">12sp</item> </style>
2.3 底部導航欄邏輯程式碼
任務分析:
在底部導航欄中點選不同的按鈕或者滑動ViewPager控制元件載入的頁面載入的頁面會切換到不同的介面,因此需要為4個按鈕設定選中狀態的監聽與ViewPager頁面切換的監聽。
任務實施:
(1)獲取介面控制元件。MainActivity類中初始化方法initView(),用於獲取標題欄、頁面中間部分及底部導航欄介面所要使用到的控制元件,並設定RadioGroup選中狀態的監聽與ViewPager頁面切換的監聽。
(2)退出本應用。為了減少執行記憶體的佔用,在不使用該應用時應該及時退出,因此需要在MainActivity中重寫onKeyDown()方法,在該方法中呼叫System.exit()退出本應用。
MainActivity.java
public class MainActivity extends AppCompatActivity { private ViewPager viewPager; private RadioGroup radioGroup; @RequiresApi(api = Build.VERSION_CODES.HONEYCOMB) private TextView tv_main_title; private RelativeLayout rl_title_bar; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); } private void initView() { tv_main_title = (TextView) findViewById(R.id.tv_main_title); tv_main_title.setText("首頁"); rl_title_bar = (RelativeLayout) findViewById(R.id.title_bar); rl_title_bar.setBackgroundColor(getResources().getColor(R.color. rdTextColorPress)); radioGroup = (RadioGroup) findViewById(R.id.radioGroup); //RadioGroup選中狀態改變監聽 radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() { @Override public void onCheckedChanged(RadioGroup group, int checkedId) { switch (checkedId) { case R.id.rb_home: //setCurrentItem()方法中第二個引數控制頁面切換動畫,true:開啟,false:關閉 viewPager.setCurrentItem(0, false); break; case R.id.rb_count: viewPager.setCurrentItem(1, false); break; case R.id.rb_video: viewPager.setCurrentItem(2, false); break; case R.id.rb_me: viewPager.setCurrentItem(3, false); break; } } }); viewPager = (ViewPager) findViewById(R.id.viewPager); /**此處後續新增**/ //ViewPager頁面切換監聽 viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() { @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override public void onPageSelected(int position) { switch (position) { case 0: radioGroup.check(R.id.rb_home); tv_main_title.setText("首頁"); rl_title_bar.setVisibility(View.VISIBLE); break; case 1: radioGroup.check(R.id.rb_count); tv_main_title.setText("統計"); rl_title_bar.setVisibility(View.VISIBLE); break; case 2: radioGroup.check(R.id.rb_video); tv_main_title.setText("視訊"); rl_title_bar.setVisibility(View.VISIBLE); break; case 3: radioGroup.check(R.id.rb_me); rl_title_bar.setVisibility(View.GONE); break; } } @Override public void onPageScrollStateChanged(int state) { } }); } protected long exitTime; //記錄第一次點選時的時間 @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN) { if ((System.currentTimeMillis() - exitTime) > 2000) { Toast.makeText(MainActivity.this, "再按一次退出黑馬頭條", Toast.LENGTH_SHORT).show(); exitTime = System.currentTimeMillis(); } else { MainActivity.this.finish(); System.exit(0); } return true; } return super.onKeyDown(keyCode, event); } }
此模組主要包括歡迎介面與底部導航欄,這兩個介面相對比較簡單。後續繼續在路上~