Android使用底部導(dǎo)航2018-08-16

Android使用底部導(dǎo)航

Android?底部導(dǎo)航停留在屏幕底部,提供應(yīng)用中頂級(jí)視圖之間的導(dǎo)航笔呀。這是在具有向后兼容性的設(shè)計(jì)支持庫中引入的幢踏。當(dāng)應(yīng)用程序有三到五個(gè)頂級(jí)導(dǎo)航時(shí),應(yīng)使用底部導(dǎo)航许师。

本文介紹了底部導(dǎo)航的基礎(chǔ)知識(shí)房蝉,并將其與Fragments相結(jié)合。我們還將學(xué)習(xí)如何通過HTTP調(diào)用獲取JSON?來加載帶有網(wǎng)格數(shù)據(jù)的第一個(gè)片段(使用RecyclerView)微渠。

下載代碼下載.APK

1.底部導(dǎo)航

可以使用BottomNavigationView組件輕松添加底部導(dǎo)航搭幻。您必須使用引力或相對(duì)屬性才能使其顯示在屏幕底部。


http://schemas.android.com/apk/res/android"

????xmlns:app="http://schemas.android.com/apk/res-auto"

????xmlns:tools="http://schemas.android.com/tools">



????????android:id="@+id/frame_container"

????????android:layout_width="match_parent"

????????android:layout_height="match_parent"

????????app:layout_behavior="@string/appbar_scrolling_view_behavior"/>



????????android:id="@+id/navigation"

????????android:layout_width="match_parent"

????????android:layout_height="wrap_content"

????????android:layout_gravity="bottom"

????????android:background="?android:attr/windowBackground"

????????app:itemBackground="@color/bgBottomNavigation"

????????android:foreground="?attr/selectableItemBackground"

????????app:itemIconTint="@android:color/white"

????????app:itemTextColor="@android:color/white"

????????app:menu="@menu/navigation"/>


這里必須記下幾個(gè)重要的屬性逞盆。

app:menu?- 用于顯示導(dǎo)航項(xiàng)以及圖標(biāo)和文本的菜單資源文件粗卜。

app:itemBackground?- 將背景顏色應(yīng)用于底部導(dǎo)航。

app:itemTextColor?- 底部導(dǎo)航項(xiàng)的文本顏色纳击。

app:itemIconTint?- 底部導(dǎo)航項(xiàng)的圖標(biāo)顏色续扔。

何時(shí)使用底部導(dǎo)航?

根據(jù)設(shè)計(jì)規(guī)范焕数,應(yīng)根據(jù)標(biāo)準(zhǔn)使用以下導(dǎo)航纱昧。

>?導(dǎo)航抽屜?- 當(dāng)頂級(jí)導(dǎo)航具有六個(gè)以上的目的地時(shí)使用。

>?標(biāo)簽?- 當(dāng)有兩個(gè)導(dǎo)航目的地時(shí)使用堡赔。

>?底部導(dǎo)航?- 當(dāng)有五個(gè)頂級(jí)目的地時(shí)使用识脆。

在進(jìn)一步研究之前,請(qǐng)快速了解底部導(dǎo)航的設(shè)計(jì)規(guī)范

現(xiàn)在讓我們通過在Android Studio中創(chuàng)建一個(gè)新項(xiàng)目來嘗試它灼捂。

2.創(chuàng)建新項(xiàng)目

1离例。從File?NewProject在Android Studio中創(chuàng)建一個(gè)新項(xiàng)目,然后從模板中選擇Basic Activity悉稠。

2宫蛆。下載此res文件夾并將drawable添加到項(xiàng)目的res。此文件夾包含底部導(dǎo)航項(xiàng)所需的必要繪圖的猛。

3耀盗。請(qǐng)確保您有設(shè)計(jì)支持庫在你的build.gradle

的build.gradle

dependencies {

????implementation 'com.android.support:design:26.1.0'

}

4卦尊。將以下顏色叛拷,字符串值添加到colors.xmlstrings.xml中

colors.xml


????#7b4bff

????#6539ba

????#FF4081

????#fe485a

strings.xml中

????Bottom Navigation

????Shop

????Gifts

????Cart

????Profile

5岂却。當(dāng)使用菜單文件呈現(xiàn)底部導(dǎo)航項(xiàng)時(shí)忿薇,在res?菜單文件夾下創(chuàng)建一個(gè)名為navigation.xml的新xml?。

navigation.xml


http://schemas.android.com/apk/res/android">



????????android:id="@+id/navigation_shop"

????????android:icon="@drawable/ic_store_white_24dp"

????????android:title="@string/title_shop"/>



????????android:id="@+id/navigation_gifts"

????????android:icon="@drawable/ic_card_giftcard_white_24dp"

????????android:title="@string/title_gifts"/>



????????android:id="@+id/navigation_cart"

????????android:icon="@drawable/ic_shopping_cart_white_24dp"

????????android:title="@string/title_cart"/>



????????android:id="@+id/navigation_profile"

????????android:icon="@drawable/ic_person_white_24dp"

????????android:title="@string/title_profile"/>


6躏哩。打開主要活動(dòng)的布局文件署浩,即activity_main.xml,并添加BottomNavigationView小部件震庭。這里我們還添加了一個(gè)FrameLayout來在選擇導(dǎo)航項(xiàng)時(shí)加載Fragments瑰抵。

activity_main.xml中


http://schemas.android.com/apk/res/android"

????xmlns:app="http://schemas.android.com/apk/res-auto"

????xmlns:tools="http://schemas.android.com/tools"

????android:id="@+id/container"

????android:layout_width="match_parent"

????android:layout_height="match_parent"

????tools:context="info.androidhive.bottomnavigation.MainActivity">



????????android:id="@+id/frame_container"

????????android:layout_width="match_parent"

????????android:layout_height="match_parent"

????????app:layout_behavior="@string/appbar_scrolling_view_behavior"/>



????????android:id="@+id/navigation"

????????android:layout_width="match_parent"

????????android:layout_height="wrap_content"

????????android:layout_gravity="bottom"

????????android:background="?android:attr/windowBackground"

????????app:itemBackground="@color/bgBottomNavigation"

????????android:foreground="?attr/selectableItemBackground"

????????app:itemIconTint="@android:color/white"

????????app:itemTextColor="@android:color/white"

????????app:menu="@menu/navigation"/>


7∧愦疲現(xiàn)在打開MainActivity.java并按如下所示進(jìn)行修改器联。

>此處,選擇底部導(dǎo)航項(xiàng)時(shí)將調(diào)用OnNavigationItemSelectedListener⌒稣福現(xiàn)在我們只是在選擇導(dǎo)航項(xiàng)時(shí)更改工具欄標(biāo)題拨拓。

MainActivity.java

packageinfo.androidhive.bottomnavigation;


importandroid.os.Bundle;

importandroid.support.annotation.NonNull;

importandroid.support.design.widget.BottomNavigationView;

importandroid.support.design.widget.CoordinatorLayout;

importandroid.support.v4.app.Fragment;

importandroid.support.v4.app.FragmentTransaction;

importandroid.support.v7.app.ActionBar;

importandroid.support.v7.app.AppCompatActivity;

importandroid.view.MenuItem;


importinfo.androidhive.bottomnavigation.fragment.CartFragment;

importinfo.androidhive.bottomnavigation.fragment.GiftsFragment;

importinfo.androidhive.bottomnavigation.fragment.ProfileFragment;

importinfo.androidhive.bottomnavigation.fragment.StoreFragment;

importinfo.androidhive.bottomnavigation.helper.BottomNavigationBehavior;


publicclassMainActivity extendsAppCompatActivity {


????privateActionBar toolbar;


????@Override

????protectedvoidonCreate(Bundle savedInstanceState) {

????????super.onCreate(savedInstanceState);

????????setContentView(R.layout.activity_main);


????????toolbar = getSupportActionBar();


????????BottomNavigationView navigation = (BottomNavigationView) findViewById(R.id.navigation);

????????navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);


????????toolbar.setTitle("Shop");

????}


????privateBottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener

????????????= newBottomNavigationView.OnNavigationItemSelectedListener() {


????????@Override

????????publicbooleanonNavigationItemSelected(@NonNullMenuItem item) {

????????????Fragment fragment;

????????????switch(item.getItemId()) {

????????????????caseR.id.navigation_shop:

????????????????????toolbar.setTitle("Shop");

????????????????????returntrue;

????????????????caseR.id.navigation_gifts:

????????????????????toolbar.setTitle("My Gifts");

????????????????????returntrue;

????????????????caseR.id.navigation_cart:

????????????????????toolbar.setTitle("Cart");

????????????????????returntrue;

????????????????caseR.id.navigation_profile:

????????????????????toolbar.setTitle("Profile");

????????????????????returntrue;

????????????}

????????????returnfalse;

????????}

????};

}

如果您運(yùn)行該應(yīng)用程序,則可以看到顯示的底部導(dǎo)航氓栈,如下所示渣磷。

3.添加片段

當(dāng)我們準(zhǔn)備好底部導(dǎo)航時(shí),讓我們看看如何在選擇導(dǎo)航菜單項(xiàng)時(shí)切換視圖授瘦。這可以通過使用片段輕松完成醋界。

注意:根據(jù)設(shè)計(jì)規(guī)范使用底部導(dǎo)航時(shí)不應(yīng)使用ViewPager(避免使用橫向運(yùn)動(dòng)在視圖之間轉(zhuǎn)換)

我創(chuàng)建一個(gè)名為四個(gè)片段StoreFragmentGiftsFragment提完,CartFragmentProfileFragment形纺。

8。通過轉(zhuǎn)到文件?新?片段?片段(空白)創(chuàng)建新片段并將其命名為StoreFragment.java徒欣。同樣也要?jiǎng)?chuàng)建其他三個(gè)片段逐样。

9。打開MainActivity.java并修改底部導(dǎo)航偵聽器,如下所示脂新,以在FrameLayout中加載片段挪捕。

>?loadFragment()?- 將Fragment加載到FrameLayout中。通過傳遞適當(dāng)?shù)钠螌?shí)例争便,在OnNavigationItemSelectedListener回調(diào)中調(diào)用相同的方法级零。

>特定模塊所需的邏輯進(jìn)入適當(dāng)?shù)钠危3諱ainActivity清潔始花。

MainActivity.java

packageinfo.androidhive.bottomnavigation;


importandroid.os.Bundle;

importandroid.support.annotation.NonNull;

importandroid.support.design.widget.BottomNavigationView;

importandroid.support.design.widget.CoordinatorLayout;

importandroid.support.v4.app.Fragment;

importandroid.support.v4.app.FragmentTransaction;

importandroid.support.v7.app.ActionBar;

importandroid.support.v7.app.AppCompatActivity;

importandroid.view.MenuItem;


importinfo.androidhive.bottomnavigation.fragment.CartFragment;

importinfo.androidhive.bottomnavigation.fragment.GiftsFragment;

importinfo.androidhive.bottomnavigation.fragment.ProfileFragment;

importinfo.androidhive.bottomnavigation.fragment.StoreFragment;

importinfo.androidhive.bottomnavigation.helper.BottomNavigationBehavior;


publicclassMainActivity extendsAppCompatActivity {


????privateActionBar toolbar;


????@Override

????protectedvoidonCreate(Bundle savedInstanceState) {

????????super.onCreate(savedInstanceState);

????????setContentView(R.layout.activity_main);


????????toolbar = getSupportActionBar();


????????// load the store fragment by default

????????toolbar.setTitle("Shop");

????????loadFragment(newStoreFragment());

????}


????privateBottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener

????????????= newBottomNavigationView.OnNavigationItemSelectedListener() {


????????@Override

????????publicbooleanonNavigationItemSelected(@NonNullMenuItem item) {

????????????Fragment fragment;

????????????switch(item.getItemId()) {

????????????????caseR.id.navigation_shop:

????????????????????toolbar.setTitle("Shop");

????????????????????fragment = newStoreFragment();

????????????????????loadFragment(fragment);

????????????????????returntrue;

????????????????caseR.id.navigation_gifts:

????????????????????toolbar.setTitle("My Gifts");

????????????????????fragment = newGiftsFragment();

????????????????????loadFragment(fragment);

????????????????????returntrue;

????????????????caseR.id.navigation_cart:

????????????????????toolbar.setTitle("Cart");

????????????????????fragment = newCartFragment();

????????????????????loadFragment(fragment);

????????????????????returntrue;

????????????????caseR.id.navigation_profile:

????????????????????toolbar.setTitle("Profile");

????????????????????fragment = newProfileFragment();

????????????????????loadFragment(fragment);

????????????????????returntrue;

????????????}


????????????returnfalse;

????????}

????};


????privatevoidloadFragment(Fragment fragment) {

????????// load fragment

????????FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();

????????transaction.replace(R.id.frame_container, fragment);

????????transaction.addToBackStack(null);

????????transaction.commit();

????}


}

現(xiàn)在妄讯,如果您運(yùn)行項(xiàng)目,則可以在選擇導(dǎo)航時(shí)看到加載的片段酷宵。

4.實(shí)現(xiàn)ShopFragment - 在網(wǎng)格中顯示項(xiàng)目

現(xiàn)在我們將看到如何實(shí)現(xiàn)第一個(gè)片段亥贸,即ShopFragment,它以網(wǎng)格方式顯示商店項(xiàng)目浇垦。為了演示炕置,我創(chuàng)建了一個(gè)樣本json,其中包含很少的待售電影男韧。要實(shí)現(xiàn)這一點(diǎn)朴摊,我們所要做的就是獲取json并以網(wǎng)格格式在RecyclerView中顯示數(shù)據(jù)。為了使任務(wù)更簡(jiǎn)單此虑,請(qǐng)按照我的另一篇解釋相同的文章甚纲。

https://api.androidhive.info/json/movies_2017.json

10。打開build.gradle并添加RecyclerView朦前,CardView介杆,VolleyGlide依賴項(xiàng)。

的build.gradle

dependencies {

????// RecyclerView

????compile 'com.android.support:recyclerview-v7:26.1.0'


????// CardView

????compile 'com.android.support:cardview-v7:26.1.0'


????// volley http library

????implementation 'com.android.volley:volley:1.0.0'

????implementation 'com.google.code.gson:gson:2.6.2'


????// glide image library

????implementation 'com.github.bumptech.glide:glide:4.3.1'

}

11韭寸。創(chuàng)建一個(gè)名為MyApplication.java的類春哨,從Application實(shí)現(xiàn)該類。這是一個(gè)單例類恩伺,其中將啟動(dòng)齊射庫赴背。

MyApplication.java

packageinfo.androidhive.bottomnavigation.app;


importandroid.app.Application;

importandroid.text.TextUtils;


importcom.android.volley.Request;

importcom.android.volley.RequestQueue;

importcom.android.volley.toolbox.Volley;


publicclassMyApplication extendsApplication {


????publicstaticfinalString TAG = MyApplication.class

????????????.getSimpleName();


????privateRequestQueue mRequestQueue;


????privatestaticMyApplication mInstance;


????@Override

????publicvoidonCreate() {

????????super.onCreate();

????????mInstance = this;

????}


????publicstaticsynchronizedMyApplication getInstance() {

????????returnmInstance;

????}


????publicRequestQueue getRequestQueue() {

????????if(mRequestQueue == null) {

????????????mRequestQueue = Volley.newRequestQueue(getApplicationContext());

????????}


????????returnmRequestQueue;

????}


????public voidaddToRequestQueue(Request req, String tag) {

????????// set the default tag if tag is empty

????????req.setTag(TextUtils.isEmpty(tag) ? TAG : tag);

????????getRequestQueue().add(req);

????}


????public voidaddToRequestQueue(Request req) {

????????req.setTag(TAG);

????????getRequestQueue().add(req);

????}


????publicvoidcancelPendingRequests(Object tag) {

????????if(mRequestQueue != null) {

????????????mRequestQueue.cancelAll(tag);

????????}

????}

}

12。打開AndroidManifest.xml并將MyApplication添加到標(biāo)記晶渠。我們還需要INTERNET權(quán)限才能進(jìn)行http調(diào)用凰荚。

AndroidManifest.xml中


http://schemas.android.com/apk/res/android"

????package="info.androidhive.bottomnavigation">


????



????????android:name=".app.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">


????????????android:name=".MainActivity"

????????????android:label="@string/app_name">

????????????

????????????????


????????????????




13。打開StoreFragment的布局文件褒脯,即fragment_store.xml便瑟,并添加下面的布局代碼。這里我們添加了RecyclerView組件憨颠。

fragment_store.xml

http://schemas.android.com/apk/res/android"

????xmlns:tools="http://schemas.android.com/tools"

????android:layout_width="match_parent"

????android:layout_height="match_parent"

????android:background="#f1f5f7"

????tools:context="info.androidhive.bottomnavigation.fragment.StoreFragment">



????????android:layout_width="match_parent"

????????android:layout_height="match_parent"

????????android:orientation="vertical">



????????????android:layout_width="match_parent"

????????????android:layout_height="wrap_content"

????????????android:paddingLeft="@dimen/activity_horizontal_margin"

????????????android:paddingTop="10dp"

????????????android:text="New Release Films"

????????????android:textColor="#111"

????????????android:textSize="16dp"/>



????????????android:id="@+id/recycler_view"

????????????android:layout_width="match_parent"

????????????android:layout_height="wrap_content"

????????????android:clipToPadding="false"

????????????android:scrollbars="vertical"/>


14胳徽。在res?布局下創(chuàng)建名為store_item_row.xml的xml?布局积锅。此布局文件將在RecyclerView適配器類中用于呈現(xiàn)單個(gè)項(xiàng)目。

store_item_row.xml

http://schemas.android.com/apk/res/android"

????xmlns:card_view="http://schemas.android.com/apk/res-auto"

????android:layout_width="match_parent"

????android:layout_height="wrap_content">



????????android:id="@+id/card_view"

????????android:layout_width="match_parent"

????????android:layout_height="match_parent"

????????android:layout_gravity="center"

????????android:layout_margin="@dimen/card_margin"

????????android:clickable="true"

????????android:elevation="3dp"

????????android:foreground="?attr/selectableItemBackground"

????????card_view:cardCornerRadius="@dimen/card_album_radius">



????????????android:layout_width="match_parent"

????????????android:layout_height="match_parent">



????????????????android:id="@+id/thumbnail"

????????????????android:layout_width="match_parent"

????????????????android:layout_height="@dimen/album_cover_height"

????????????????android:background="?attr/selectableItemBackgroundBorderless"

????????????????android:clickable="true"

????????????????android:scaleType="fitXY"/>



????????????????android:id="@+id/title"

????????????????android:layout_width="match_parent"

????????????????android:layout_height="wrap_content"

????????????????android:layout_below="@id/thumbnail"

????????????????android:lines="2"

????????????????android:paddingLeft="@dimen/album_title_padding"

????????????????android:paddingRight="@dimen/album_title_padding"

????????????????android:paddingTop="@dimen/album_title_padding"

????????????????android:textColor="#111"

????????????????android:textSize="11dp"/>



????????????????android:id="@+id/price"

????????????????android:layout_width="match_parent"

????????????????android:layout_height="wrap_content"

????????????????android:layout_below="@id/title"

????????????????android:layout_marginRight="10dp"

????????????????android:gravity="right"

????????????????android:paddingBottom="@dimen/songs_count_padding_bottom"

????????????????android:textColor="@color/colorAccent"

????????????????android:textSize="11dp"/>





15养盗。創(chuàng)建一個(gè)名為Movie.java的類缚陷。解析json時(shí),此POJO類將非常有用往核。

Movie.java

packageinfo.androidhive.bottomnavigation;


publicclassMovie {

????String title;

????String image;

????String price;


????publicString getTitle() {

????????returntitle;

????}


????publicvoidsetTitle(String title) {

????????this.title = title;

????}


????publicString getImage() {

????????returnimage;

????}


????publicvoidsetImage(String image) {

????????this.image = image;

????}


????publicString getPrice() {

????????returnprice;

????}


????publicvoidsetPrice(String price) {

????????this.price = price;

????}

}

16◇镆現(xiàn)在打開StoreFragment.java并添加下面的代碼。為簡(jiǎn)單起見聂儒,RecyclerView適配器類StoreAdapter包含在同一個(gè)片段中虎锚。

>?fetchStoreItems()方法使用Volley獲取電影json并使用Gson對(duì)其進(jìn)行序列化。

>?StoreAdapter類在RecyclerView中呈現(xiàn)電影衩婚。

StoreFragment.java

packageinfo.androidhive.bottomnavigation.fragment;



importandroid.content.Context;

importandroid.content.res.Resources;

importandroid.graphics.Rect;

importandroid.os.Bundle;

importandroid.support.v4.app.Fragment;

importandroid.support.v7.widget.DefaultItemAnimator;

importandroid.support.v7.widget.GridLayoutManager;

importandroid.support.v7.widget.RecyclerView;

importandroid.util.Log;

importandroid.util.TypedValue;

importandroid.view.LayoutInflater;

importandroid.view.View;

importandroid.view.ViewGroup;

importandroid.widget.ImageView;

importandroid.widget.TextView;

importandroid.widget.Toast;


importcom.android.volley.Response;

importcom.android.volley.VolleyError;

importcom.android.volley.toolbox.JsonArrayRequest;

importcom.bumptech.glide.Glide;

importcom.google.gson.Gson;

importcom.google.gson.reflect.TypeToken;


importorg.json.JSONArray;


importjava.util.ArrayList;

importjava.util.List;


importinfo.androidhive.bottomnavigation.Movie;

importinfo.androidhive.bottomnavigation.app.MyApplication;

importinfo.androidhive.bottomnavigation.R;


publicclassStoreFragment extendsFragment {


????privatestaticfinalString TAG = StoreFragment.class.getSimpleName();

????privatestaticfinalString URL = "https://api.androidhive.info/json/movies_2017.json";


????privateRecyclerView recyclerView;

????privateList movieList;

????privateStoreAdapter mAdapter;


????publicStoreFragment() {

????????// Required empty public constructor

????}


????publicstaticStoreFragment newInstance(String param1, String param2) {

????????StoreFragment fragment = newStoreFragment();

????????Bundle args = newBundle();

????????fragment.setArguments(args);

????????returnfragment;

????}


????@Override

????publicvoidonCreate(Bundle savedInstanceState) {

????????super.onCreate(savedInstanceState);

????}


????@Override

????publicView onCreateView(LayoutInflater inflater, ViewGroup container,

?????????????????????????????Bundle savedInstanceState) {

????????// Inflate the layout for this fragment

????????View view = inflater.inflate(R.layout.fragment_store, container, false);


????????recyclerView = view.findViewById(R.id.recycler_view);

????????movieList = newArrayList<>();

????????mAdapter = newStoreAdapter(getActivity(), movieList);


????????RecyclerView.LayoutManager mLayoutManager = newGridLayoutManager(getActivity(), 3);

????????recyclerView.setLayoutManager(mLayoutManager);

????????recyclerView.addItemDecoration(newGridSpacingItemDecoration(2, dpToPx(8), true));

????????recyclerView.setItemAnimator(newDefaultItemAnimator());

????????recyclerView.setAdapter(mAdapter);

????????recyclerView.setNestedScrollingEnabled(false);


????????fetchStoreItems();


????????returnview;

????}


????privatevoidfetchStoreItems() {

????????JsonArrayRequest request = newJsonArrayRequest(URL,

????????????????newResponse.Listener() {

????????????????????@Override

????????????????????publicvoidonResponse(JSONArray response) {

????????????????????????if(response == null) {

????????????????????????????Toast.makeText(getActivity(), "Couldn't fetch the store items! Pleas try again.", Toast.LENGTH_LONG).show();

????????????????????????????return;

????????????????????????}


????????????????????????List items = newGson().fromJson(response.toString(), newTypeToken>() {

????????????????????????}.getType());


????????????????????????movieList.clear();

????????????????????????movieList.addAll(items);


????????????????????????// refreshing recycler view

????????????????????????mAdapter.notifyDataSetChanged();

????????????????????}

????????????????}, newResponse.ErrorListener() {

????????????@Override

????????????publicvoidonErrorResponse(VolleyError error) {

????????????????// error in getting json

????????????????Log.e(TAG, "Error: "+ error.getMessage());

????????????????Toast.makeText(getActivity(), "Error: "+ error.getMessage(), Toast.LENGTH_SHORT).show();

????????????}

????????});


????????MyApplication.getInstance().addToRequestQueue(request);

????}


????publicclassGridSpacingItemDecoration extendsRecyclerView.ItemDecoration {


????????privateintspanCount;

????????privateintspacing;

????????privatebooleanincludeEdge;


????????publicGridSpacingItemDecoration(intspanCount, intspacing, booleanincludeEdge) {

????????????this.spanCount = spanCount;

????????????this.spacing = spacing;

????????????this.includeEdge = includeEdge;

????????}


????????@Override

????????publicvoidgetItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {

????????????intposition = parent.getChildAdapterPosition(view); // item position

????????????intcolumn = position % spanCount; // item column


????????????if(includeEdge) {

????????????????outRect.left = spacing - column * spacing / spanCount; // spacing - column * ((1f / spanCount) * spacing)

????????????????outRect.right = (column + 1) * spacing / spanCount; // (column + 1) * ((1f / spanCount) * spacing)


????????????????if(position < spanCount) { // top edge

????????????????????outRect.top = spacing;

????????????????}

????????????????outRect.bottom = spacing; // item bottom

????????????} else{

????????????????outRect.left = column * spacing / spanCount; // column * ((1f / spanCount) * spacing)

????????????????outRect.right = spacing - (column + 1) * spacing / spanCount; // spacing - (column + 1) * ((1f /??? spanCount) * spacing)

????????????????if(position >= spanCount) {

????????????????????outRect.top = spacing; // item top

????????????????}

????????????}

????????}

????}


????/**

?????* Converting dp to pixel

?????*/

????privateintdpToPx(intdp) {

????????Resources r = getResources();

????????returnMath.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, r.getDisplayMetrics()));

????}


????classStoreAdapter extendsRecyclerView.Adapter {

????????privateContext context;

????????privateList movieList;


????????publicclassMyViewHolder extendsRecyclerView.ViewHolder {

????????????publicTextView name, price;

????????????publicImageView thumbnail;


????????????publicMyViewHolder(View view) {

????????????????super(view);

????????????????name = view.findViewById(R.id.title);

????????????????price = view.findViewById(R.id.price);

????????????????thumbnail = view.findViewById(R.id.thumbnail);

????????????}

????????}



????????publicStoreAdapter(Context context, List movieList) {

????????????this.context = context;

????????????this.movieList = movieList;

????????}


????????@Override

????????publicMyViewHolder onCreateViewHolder(ViewGroup parent, intviewType) {

????????????View itemView = LayoutInflater.from(parent.getContext())

????????????????????.inflate(R.layout.store_item_row, parent, false);


????????????returnnewMyViewHolder(itemView);

????????}


????????@Override

????????publicvoidonBindViewHolder(MyViewHolder holder, finalintposition) {

????????????finalMovie movie = movieList.get(position);

????????????holder.name.setText(movie.getTitle());

????????????holder.price.setText(movie.getPrice());


????????????Glide.with(context)

????????????????????.load(movie.getImage())

????????????????????.into(holder.thumbnail);

????????}


????????@Override

????????publicintgetItemCount() {

????????????returnmovieList.size();

????????}

????}

}

現(xiàn)在窜护,如果您運(yùn)行該應(yīng)用程序,您可以看到ShopFragment以網(wǎng)格方式顯示電影非春。同樣柱徙,您也可以實(shí)現(xiàn)其他片段。

5.在滾動(dòng)條上隱藏底部導(dǎo)航

根據(jù)設(shè)計(jì)規(guī)范奇昙,滾動(dòng)內(nèi)容時(shí)必須隱藏底部導(dǎo)航护侮,從而為屏幕上的內(nèi)容提供更多空間。為此储耐,我們需要將BottomNavigationBehavior附加到底部導(dǎo)航羊初。

17。使用以下代碼創(chuàng)建名為BottomNavigationBehavior.java的類什湘。

BottomNavigationBehavior.java

packageinfo.androidhive.bottomnavigation.helper;


importandroid.content.Context;

importandroid.support.design.widget.BottomNavigationView;

importandroid.support.design.widget.CoordinatorLayout;

importandroid.support.v4.view.ViewCompat;

importandroid.util.AttributeSet;

importandroid.view.View;

importandroid.widget.FrameLayout;


publicclassBottomNavigationBehavior extendsCoordinatorLayout.Behavior {


????publicBottomNavigationBehavior() {

????????super();

????}


????publicBottomNavigationBehavior(Context context, AttributeSet attrs) {

????????super(context, attrs);

????}


????@Override

????publicbooleanlayoutDependsOn(CoordinatorLayout parent, BottomNavigationView child, View dependency) {

????????booleandependsOn = dependency instanceofFrameLayout;

????????returndependsOn;

????}


????@Override

????publicbooleanonStartNestedScroll(CoordinatorLayout coordinatorLayout, BottomNavigationView child, View directTargetChild, View target, intnestedScrollAxes) {

????????returnnestedScrollAxes == ViewCompat.SCROLL_AXIS_VERTICAL;

????}


????@Override

????publicvoidonNestedPreScroll(CoordinatorLayout coordinatorLayout, BottomNavigationView child, View target, intdx, intdy, int[] consumed) {

????????if(dy < 0) {

????????????showBottomNavigationView(child);

????????} elseif(dy > 0) {

????????????hideBottomNavigationView(child);

????????}

????}


????privatevoidhideBottomNavigationView(BottomNavigationView view) {

????????view.animate().translationY(view.getHeight());

????}


????privatevoidshowBottomNavigationView(BottomNavigationView view) {

????????view.animate().translationY(0);

????}

}

18长赞。添加BottomNavigationBehavior使用setBehavior()MainActivity.java如下所示。

MainActivity.java

publicclassMainActivity extendsAppCompatActivity {


????privateActionBar toolbar;


????@Override

????protectedvoidonCreate(Bundle savedInstanceState) {

????????super.onCreate(savedInstanceState);

????????setContentView(R.layout.activity_main);


????????BottomNavigationView navigation = (BottomNavigationView) findViewById(R.id.navigation);

????????navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);


????????// attaching bottom sheet behaviour - hide / show on scroll

????????CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) navigation.getLayoutParams();

????????layoutParams.setBehavior(newBottomNavigationBehavior());


????????// load the store fragment by default

????????// ..

????}

}

現(xiàn)在禽炬,如果您測(cè)試應(yīng)用程序涧卵,則可以在滾動(dòng)應(yīng)用程序內(nèi)容時(shí)看到底部導(dǎo)航向下滑動(dòng)勤家。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末腹尖,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子伐脖,更是在濱河造成了極大的恐慌热幔,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,348評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件讼庇,死亡現(xiàn)場(chǎng)離奇詭異绎巨,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)蠕啄,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,122評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門场勤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來戈锻,“玉大人,你說我怎么就攤上這事和媳「裨猓” “怎么了?”我有些...
    開封第一講書人閱讀 156,936評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵留瞳,是天一觀的道長(zhǎng)拒迅。 經(jīng)常有香客問我,道長(zhǎng)她倘,這世上最難降的妖魔是什么璧微? 我笑而不...
    開封第一講書人閱讀 56,427評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮硬梁,結(jié)果婚禮上前硫,老公的妹妹穿的比我還像新娘。我一直安慰自己荧止,他們只是感情好开瞭,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,467評(píng)論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著罩息,像睡著了一般嗤详。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上瓷炮,一...
    開封第一講書人閱讀 49,785評(píng)論 1 290
  • 那天葱色,我揣著相機(jī)與錄音,去河邊找鬼娘香。 笑死苍狰,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的烘绽。 我是一名探鬼主播淋昭,決...
    沈念sama閱讀 38,931評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼安接!你這毒婦竟也來了翔忽?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,696評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤盏檐,失蹤者是張志新(化名)和其女友劉穎歇式,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體胡野,經(jīng)...
    沈念sama閱讀 44,141評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡材失,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,483評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了硫豆。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片龙巨。...
    茶點(diǎn)故事閱讀 38,625評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡笼呆,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出旨别,到底是詐尸還是另有隱情抄邀,我是刑警寧澤,帶...
    沈念sama閱讀 34,291評(píng)論 4 329
  • 正文 年R本政府宣布昼榛,位于F島的核電站境肾,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏胆屿。R本人自食惡果不足惜奥喻,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,892評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望非迹。 院中可真熱鬧环鲤,春花似錦、人聲如沸憎兽。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽纯命。三九已至西剥,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間亿汞,已是汗流浹背瞭空。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評(píng)論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留疗我,地道東北人咆畏。 一個(gè)月前我還...
    沈念sama閱讀 46,324評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像吴裤,于是被迫代替她去往敵國和親旧找。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,492評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,757評(píng)論 25 707
  • 用兩張圖告訴你麦牺,為什么你的 App 會(huì)卡頓? - Android - 掘金 Cover 有什么料钮蛛? 從這篇文章中你...
    hw1212閱讀 12,699評(píng)論 2 59
  • RecyclerView的介紹是android世界發(fā)生的最好的事情。您可以使用RecyclerView創(chuàng)建令人驚嘆...
    ListenToCode閱讀 714評(píng)論 0 2
  • 1 我有一件黑色的襯衣枕面。 依稀記得是在來上海讀書之前愿卒,某年某日與媽媽在家鄉(xiāng)閑逛時(shí)買下的缚去,麻布材質(zhì)潮秘,大眾版型,只是當(dāng)...
    郁文堂閱讀 241評(píng)論 0 2
  • 今天星期一易结,假期的第二天枕荞,外面的天氣應(yīng)該很熱了柜候,五一,假期躏精,是黃金周渣刷,是旅游的好季節(jié)。別人家都帶孩子出去旅...
    夏雯敏閱讀 137評(píng)論 0 1