Android學習筆記- Fragment實例 底部導航欄的實現

来源:http://www.cnblogs.com/zc2014blog/archive/2017/06/11/6986750.html
-Advertisement-
Play Games

1.要實現的效果圖以及工程目錄結構: 先看看效果圖吧: 接著看看我們的工程的目錄結構: 2.實現流程: Step 1:寫下底部選項的一些資源文件 我們從圖上可以看到,我們底部的每一項點擊的時候都有不同的效果是吧! 我們是通過是否selected來判定的!我們要寫的資源文件有:首先是圖片,然後是文字, ...


1.要實現的效果圖以及工程目錄結構:

先看看效果圖吧:

接著看看我們的工程的目錄結構


2.實現流程:


Step 1:寫下底部選項的一些資源文件

我們從圖上可以看到,我們底部的每一項點擊的時候都有不同的效果是吧! 我們是通過是否selected來判定的!我們要寫的資源文件有:首先是圖片,然後是文字,接著是背景!

圖片Drawable資源:tab_menu_channel.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@mipmap/tab_channel_pressed" android:state_selected="true" />
    <item android:drawable="@mipmap/tab_channel_normal" />
</selector>

其他三個照葫蘆畫瓢!

文字資源:tab_menu_text.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="@color/text_yellow" android:state_selected="true" />
    <item android:color="@color/text_gray" />
</selector>

背景資源:tab_menu_bg.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_selected="true">
        <shape>
            <solid android:color="#FFC4C4C4" />
        </shape>
    </item>
    <item>
        <shape>
            <solid android:color="@color/transparent" />
        </shape>
    </item>
</selector>

Step 2:編寫我們的Activity佈局

activity_main.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <RelativeLayout
        android:id="@+id/ly_top_bar"
        android:layout_width="match_parent"
        android:layout_height="48dp"
        android:background="@color/bg_topbar">

        <TextView
            android:id="@+id/txt_topbar"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_centerInParent="true"
            android:gravity="center"
            android:textSize="18sp"
            android:textColor="@color/text_topbar"
            android:text="信息"/>


        <View
            android:layout_width="match_parent"
            android:layout_height="2px"
            android:background="@color/div_white"
            android:layout_alignParentBottom="true"/>

    </RelativeLayout>



    <LinearLayout
        android:id="@+id/ly_tab_bar"
        android:layout_width="match_parent"
        android:layout_height="56dp"
        android:layout_alignParentBottom="true"
        android:background="@color/bg_white"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/txt_channel"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@drawable/tab_menu_bg"
            android:drawablePadding="3dp"
            android:drawableTop="@drawable/tab_menu_channel"
            android:gravity="center"
            android:padding="5dp"
            android:text="@string/tab_menu_alert"
            android:textColor="@drawable/tab_menu_text"
            android:textSize="16sp" />

        <TextView
            android:id="@+id/txt_message"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@drawable/tab_menu_bg"
            android:drawablePadding="3dp"
            android:drawableTop="@drawable/tab_menu_message"
            android:gravity="center"
            android:padding="5dp"
            android:text="@string/tab_menu_profile"
            android:textColor="@drawable/tab_menu_text"
            android:textSize="16sp" />

        <TextView
            android:id="@+id/txt_better"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@drawable/tab_menu_bg"
            android:drawablePadding="3dp"
            android:drawableTop="@drawable/tab_menu_better"
            android:gravity="center"
            android:padding="5dp"
            android:text="@string/tab_menu_pay"
            android:textColor="@drawable/tab_menu_text"
            android:textSize="16sp" />

        <TextView
            android:id="@+id/txt_setting"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:background="@drawable/tab_menu_bg"
            android:drawablePadding="3dp"
            android:drawableTop="@drawable/tab_menu_setting"
            android:gravity="center"
            android:padding="5dp"
            android:text="@string/tab_menu_setting"
            android:textColor="@drawable/tab_menu_text"
            android:textSize="16sp"/>

    </LinearLayout>

    <View
        android:id="@+id/div_tab_bar"
        android:layout_width="match_parent"
        android:layout_height="2px"
        android:background="@color/div_white"
        android:layout_above="@id/ly_tab_bar"/>


    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@id/ly_top_bar"
        android:layout_above="@id/div_tab_bar"
        android:id="@+id/ly_content">

    </FrameLayout>

</RelativeLayout>

代碼解析:

首先定義頂部標題欄的樣式,48dp的LinearLayout中間加上一個TextView作為標題!
接著定義一個大小為56dp的LinerLayout對其底部,在這個裡面加入四個TextView,比例1:1:1:1, 並且設置相關屬性,接著在這個LinearLayout上加一條線段!
最後以標題欄和底部導航欄為邊界,寫一個FrameLayout,寬高match_parent,用做Fragment的容器!

PS:這裡四個TextView屬性是重覆的,你也可以自行抽取出來,編寫一個style,設置下~


Step 3:隱藏頂部導航欄

意外發現以前的在Activity中調用requestWindowFeature(Window.FEATURE_NO_TITLE);可以隱藏手機 自帶頂部導航欄,但是寫demo時候發現會報錯,即使這句話寫在了setContentView()之前!可能是因為 繼承的是AppCompatActivity而非Activity類!
當然以前的getSupportActionbar().hide()隱藏掉Actionbar,但是他還是會在界面上! 最後還有一種方法就是自己編寫一個style,然後在AndroidManifest.xml中為Application設置這個Theme:

註: 把 requestWindowFeature(Window.FEATURE_NO_TITLE);放在super.onCreate(savedInstanceState);前面就可以隱藏ActionBar而不報錯。

接著AndroidManifest.xml設置下theme屬性:

android:theme="@style/Theme.AppCompat.NoActionBar"

Step 4:創建一個Fragment的簡單佈局與類:

fg_content.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/bg_white">
    
    <TextView
        android:id="@+id/txt_content"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:text="呵呵"
        android:textColor="@color/text_yellow"
        android:textSize="20sp"/>

</LinearLayout>

MyFragment.java:

/**
 * Created by Coder-pig on 2015/8/28 0028.
 */
public class MyFragment extends Fragment {

    private String content;
    public MyFragment(String content) {
        this.content = content;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fg_content,container,false);
        TextView txt_content = (TextView) view.findViewById(R.id.txt_content);
        txt_content.setText(content);
        return view;
    }
}

代碼解析:

就是簡單的重寫了一個onCreateView()方法,其他方法可以按需重寫!


Step 5:編寫MainActivity.java

先說說我們要考慮的一些關鍵問題:

  • Fragment什麼時候初始化和add到容器中?什麼時候hide和show?
  • 如何讓TextView被選中?選中一個TextView後,要做一些什麼操作?
  • 剛進入MainActivity怎麼樣讓一個TextView處於Selected的狀態?

嗯,接下來一一解答上面這些問題:

  • 我們選中TextView後對對應的Fragment進行判空,如果為空,初始化,並添加到容器中; 而hide的話,我們定義一個方法hide所有的Fragment,每次觸發點擊事件就先調用這個hideAll方法, 講所有Fragment隱藏起來,然後如果TextView對應的Fragment不為空,我們就將這個Fragment顯示出來;
  • 這個我們通過點擊事件來實現,點擊TextView後先重置所有TextView的選中狀態為false,然後設置點擊的 TextView的選中狀態為true;
  • 這個更簡單,我們是通過點擊事件來設置選中的,那麼在onCreate()方法裡加個觸發點擊事件的 方法不就可以了嘛~txt_channel.performClick();

邏輯都弄懂了,直接上代碼咯:

MainActivity.java:

/**
 * Created by Coder-pig on 2015/8/28 0028.
 */
public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    //UI Object
    private TextView txt_topbar;
    private TextView txt_channel;
    private TextView txt_message;
    private TextView txt_better;
    private TextView txt_setting;
    private FrameLayout ly_content;

    //Fragment Object
    private MyFragment fg1,fg2,fg3,fg4;
    private FragmentManager fManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_main);
        fManager = getFragmentManager();
        bindViews();
        txt_channel.performClick();   //模擬一次點擊,既進去後選擇第一項
    }

    //UI組件初始化與事件綁定
    private void bindViews() {
        txt_topbar = (TextView) findViewById(R.id.txt_topbar);
        txt_channel = (TextView) findViewById(R.id.txt_channel);
        txt_message = (TextView) findViewById(R.id.txt_message);
        txt_better = (TextView) findViewById(R.id.txt_better);
        txt_setting = (TextView) findViewById(R.id.txt_setting);
        ly_content = (FrameLayout) findViewById(R.id.ly_content);

        txt_channel.setOnClickListener(this);
        txt_message.setOnClickListener(this);
        txt_better.setOnClickListener(this);
        txt_setting.setOnClickListener(this);
    }

    //重置所有文本的選中狀態
    private void setSelected(){
        txt_channel.setSelected(false);
        txt_message.setSelected(false);
        txt_better.setSelected(false);
        txt_setting.setSelected(false);
    }

    //隱藏所有Fragment
    private void hideAllFragment(FragmentTransaction fragmentTransaction){
        if(fg1 != null)fragmentTransaction.hide(fg1);
        if(fg2 != null)fragmentTransaction.hide(fg2);
        if(fg3 != null)fragmentTransaction.hide(fg3);
        if(fg4 != null)fragmentTransaction.hide(fg4);
    }


    @Override
    public void onClick(View v) {
        FragmentTransaction fTransaction = fManager.beginTransaction();
        hideAllFragment(fTransaction);
        switch (v.getId()){
            case R.id.txt_channel:
                setSelected();
                txt_channel.setSelected(true);
                if(fg1 == null){
                    fg1 = new MyFragment("第一個Fragment");
                    fTransaction.add(R.id.ly_content,fg1);
                }else{
                    fTransaction.show(fg1);
                }
                break;
            case R.id.txt_message:
                setSelected();
                txt_message.setSelected(true);
                if(fg2 == null){
                    fg2 = new MyFragment("第二個Fragment");
                    fTransaction.add(R.id.ly_content,fg2);
                }else{
                    fTransaction.show(fg2);
                }
                break;
            case R.id.txt_better:
                setSelected();
                txt_better.setSelected(true);
                if(fg3 == null){
                    fg3 = new MyFragment("第三個Fragment");
                    fTransaction.add(R.id.ly_content,fg3);
                }else{
                    fTransaction.show(fg3);
                }
                break;
            case R.id.txt_setting:
                setSelected();
                txt_setting.setSelected(true);
                if(fg4 == null){
                    fg4 = new MyFragment("第四個Fragment");
                    fTransaction.add(R.id.ly_content,fg4);
                }else{
                    fTransaction.show(fg4);
                }
                break;
        }
        fTransaction.commit();
    }
}

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 我們知道,在 Objective-C 中可以通過 Category 給一個現有的類添加屬性,但是卻不能添加實例變數,這似乎成為了 Objective-C 的一個明顯短板。然而值得慶幸的是,我們可以通過 Associated Objects 來彌補這一不足。本文將結合 runtime 源碼深入探究 O ...
  • 文章照搬過來的:原文地址https://developer.android.google.cn/guide/components/recents.html 概覽屏幕(也稱為最新動態屏幕、最近任務列表或最近使用的應用)是一個系統級別 UI,其中列出了最近訪問過的 Activity 和任務。 用戶可以瀏 ...
  • 還是這個接手項目,二維碼掃描集成的是zxing,掃描界面的圖像有明顯的拉伸變形。 這種問題,根據以往的經驗,一般是x,y軸錯位引起的,處理好x,y軸的問題,一般可以解決問題。 由於這個問題,之前有很多人遇到,並分享在網上了,所以,我這裡也就不需要重覆造輪子了。 這裡看了一篇博客:http://blo ...
  • DrawerLayout 是 Android 官方的側滑菜單控制項,而 ViewPager 相信大家都很熟悉了。今天這裡就講一下當在 DrawerLayout 中嵌套 ViewPager 時,要如何解決滑動衝突的問題,效果如下: 首先,讓我們先來解決 DrawerLayout 和 ViewPager ...
  • 真機測試時提示Could not find Developer Disk Image.這該怎麼辦???? 這是由於真機系統過高或者過低,Xcode中沒有匹配的配置包文件,我們可以通過這個路徑進入配置包的存放目錄: /Applications/Xcode.app/Contents/Developer/ ...
  • UIKit Dynamic是iOS7 新增的一組類和方法,可賦予UIView逼真的行為和特征,不需要寫動畫效果那些繁瑣的代碼,讓開發人員能夠輕鬆地改善應用的用戶體驗。一共有6個可用於定製UIDynamicAnimator的類,這裡先只簡單介紹下碰撞的動畫效果,即UICollisionBehavior ...
  • 訂製EditText游標 設置背景android:background="@null" 設置游標樣式:android:textCursorDrawable="@drawable/edit_cursor_line" 去掉或設置游標下的圓點樣式:android:textSelectHandle="@dr ...
  • 代碼: RootViewController.m ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...