Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android M新控件知識整理

Android M新控件知識整理

編輯:關於Android編程

前言:

Google官方在14年Google I/O上推出了全新的設計語言——Material Design。一並推出了一系列實現Material Design效果的控件庫——Android Design Support Library。


Android Studio獲得Android Design Support Library庫

‘compile’com.android.support:design:22.2.1’

(一): TabLayout

Tablayout的作用一般是配合ViewPager結合Fragment一起使用,實現如下圖效果
圖1
下面就上代碼咯~<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxociAvPg0KPGg0IGlkPQ=="activityxml代碼">activity_xml代碼:




    

    

這裡對其中的一些屬性進行說明

app:tabIndicatorColor=”@color/white”// 下方滾動的下劃線顏色

app:tabSelectedTextColor=”@color/gray”// tab被選中後,文字的顏色

app:tabTextColor=”@color/white” // tab默認的文字顏色

app:tabMode=”fixed”//tab較少時均分整個屏幕

app:tabMode=”scrollable” //tab較多時,支持滑動

當然這些屬性也可以在代碼中設置:

tabLayout.setTabMode(TabLayout.MODE_FIXED);

tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);

tabLayout.setSelectedTabIndicatorColor();

tabLayout.setTabTextColors(,);注意:這裡有兩個參數分別是未選中,和選中的時候tab標簽的顏色


接著是activity代碼:

public class MainActivity extends AppCompatActivity {
    private TabLayout tabLayout;
    private ViewPager viewPager;
    private SimpleFragmentPagerAdapter pagerAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
    }
    private void initView() {
        //setupWithViewPager必須在ViewPager.setAdapter()之後調用
        /**
         也可以通過TabLayout的addTab()方法添加新構建的Tab實例到TabLayout中:
         TabLayout tabLayout = (TabLayout) findViewById(R.id.tabLayout);;
         tabLayout.addTab(tabLayout.newTab().setText("Tab 1"));
         tabLayout.addTab(tabLayout.newTab().setText("Tab 2"));
         tabLayout.addTab(tabLayout.newTab().setText("Tab 3"));
         */
        tabLayout = (TabLayout) findViewById(R.id.tabLayout);
        viewPager = (ViewPager) findViewById(R.id.viewPager);
        pagerAdapter = new SimpleFragmentPagerAdapter(getSupportFragmentManager(), this);
        viewPager.setAdapter(pagerAdapter);
        tabLayout.setupWithViewPager(viewPager);

        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        toolbar.setNavigationIcon(R.mipmap.ic_launcher);//設置導航欄圖標
        toolbar.setLogo(R.mipmap.ic_launcher);//設置app logo
        toolbar.setTitle("Title");//設置主標題
        //toolbar.setSubtitle("Subtitle");//設置子標題
        toolbar.inflateMenu(R.menu.menu_toolbar);//設置右上角的填充菜單
    }
}

說明: setupWithViewPager必須在ViewPager.setAdapter()之後調用
某些時候也可以用下面的代碼來實現TabLayout與viewpager的雙向交互

tabLayout = (TabLayout) findViewById(R.id.tabLayout);
viewPager = (ViewPager) findViewById(R.id.viewPager);
pagerAdapter = new SimpleFragmentPagerAdapter(getSupportFragmentManager(), this);
//viewPager.setAdapter(pagerAdapter);
//注意一下,setupWithViePager必須在ViewPager.setAdapter()之後調用!
//tabLayout.setupWithViewPager(viewPager);

//1.設置TabLayout的選項卡監聽
tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
    @Override
    public void onTabSelected(TabLayout.Tab tab) {
        viewPager.setCurrentItem(tab.getPosition());
        colorChange(tab.getPosition());
    }

    @Override
    public void onTabUnselected(TabLayout.Tab tab) {

    }

    @Override
    public void onTabReselected(TabLayout.Tab tab) {

    }
});
//2.設置Tab的標題來自PagerAdapter.getPageTitle()
tabLayout.setTabsFromPagerAdapter(pagerAdapter);
//3.設置TabLayout.TabLayoutOnPageChangeListener,給ViewPager
TabLayout.TabLayoutOnPageChangeListener listener =
        new TabLayout.TabLayoutOnPageChangeListener(tabLayout);
viewPager.addOnPageChangeListener(listener);
viewPager.setAdapter(pagerAdapter);

最後是adapter和fragment的代碼

public class SimpleFragmentPagerAdapter extends FragmentPagerAdapter {
    final int PAGE_COUNT = 3;
    private String tabTitles[] = new String[]{"tab1", "tab2", "tab3"};
    private Context context;

    public SimpleFragmentPagerAdapter(FragmentManager fm, Context context) {
        super(fm);
        this.context = context;
    }

    @Override
    public Fragment getItem(int position) {
        return PageFragment.newInstance(position);
    }

    @Override
    public int getCount() {
        return PAGE_COUNT;
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return tabTitles[position];
    }
}

public class PageFragment extends Fragment {
    public static final String ARGS_PAGE = "args_page";
    private int mPage;

    public static PageFragment newInstance(int page) {
        Bundle args = new Bundle();
        args.putInt(ARGS_PAGE, page);
        PageFragment fragment = new PageFragment();
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mPage = getArguments().getInt(ARGS_PAGE);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_page, container, false);
        TextView textView = (TextView) view.findViewById(R.id.textView);
        textView.setText("第" + mPage + "頁");
        return view;
    }

}

fargment的xml文件我只是放了個textview,這裡就不帖代碼了
至此就是TabLayout的簡單用法,但是我們也可以自己定義TabLayout的樣式
 

碰到的坑:

在Android Studio 1.4 ,buildToolsVersion “23.0.3”,小米2s測試機 中創建demo使用TabLayout:最外層不使用CoordinatorLayout而使用LinearLayout做為最外層根布局則界面如下圖所示,
通知欄透明變成白色,很是難看,原因是此Activity默認設置了android:theme=”@style/AppTheme.NoActionBar”這個主題
這裡寫圖片描述
我的解決辦法是:修改次Activity的主題

其中最後兩個item的作用是去除ActionBar,順便配圖一張,意會下前面3個item所代表的含義;
這裡寫圖片描述

(二): AppBarLayout、CoordinatorLayout

AppBarLayout 是繼承LinerLayout實現的一個ViewGroup容器組件,它是為了Material Design設計的App Bar,支持手勢滑動操作。默認的AppBarLayout是垂直方向的,它的作用是把AppBarLayout包裹的內容都作為AppBar,很多時候AppBarLayout都是作為Toolbar的父布局容器 CoordinatorLayout:是一個增強型的FrameLayout:它的作用有兩個
a. 作為一個布局的根布局
b. 最為一個為子視圖之間相互協調手勢效果的一個協調布局
它是組織它眾多子view之間互相協作的一個ViewGroup。CoordinatorLayout使得子view之間知道了彼此的存在,一個子view的變化可以通知到另一個子view,CoordinatorLayout 所做的事情就是當成一個通信的橋梁,連接不同的view,使用 Behavior 對象進行通信。 CoordinatorLayout + AppBarLayout(向上滾動隱藏指定的View)
1). 首先需要用CoordinatorLayout包住AppBarLayout;
2). 頂部區域的View都放在AppBarLayout裡面;
3). AppBarLayout外面,CoordinatorLayout裡面,放一個帶有可滾動的View.如下的例子,放的是ViewPager,而ViewPager裡面是放了RecylerView的,即是可以滾動的View.;
4). 在可以滾動的View上設置屬性 app:layout_behavior=”@string/appbar_scrolling_view_behavior”這個Behavior的class是真正控制滾動時候View的滾動行為
比如:在CoordinatorLayout中使用AppBarLayout,如果AppBarLayout的子View(如ToolBar、TabLayout)標記了app:layout_scrollFlags滾動事件,那麼在CoordinatorLayout布局裡其它標記了app:layout_behavior的子View(LinearLayout、RecyclerView、NestedScrollView等)就能夠響應(如ToolBar、TabLayout)控件被標記的滾動事件。
4). 在AppBarLayout裡面的View,通過app:layout_scrollFlags屬性來控制,滾動時候的表現.其中有4種Flag的類型;
scroll: 所有想滾動出屏幕的view都需要設置這個flag, 沒有設置這個flag的view將被固定在屏幕頂部。 enterAlways:這個flag讓任意向下的滾動都會導致該view變為可見,啟用快速“返回模式”。 enterAlwaysCollapsed:當你的視圖已經設置minHeight屬性又使用此標志時,你的視圖只能已最小高度進入,只有
當滾動視圖到達頂部時才擴大到完整高度。 exitUntilCollapsed:滾動退出屏幕,最後折疊在頂端。

總結:這兩個Layout暫時只是做些記錄,感覺使用的頻率不是很高。


(三): Toolbar

Toolbar是在 Android 5.0 開始推出的一個 Material Design 風格的導航控件 ,Google 非常推薦大家使用 Toolbar 來作為Android客戶端的導航欄,以此來取代之前的 Actionbar 。與 Actionbar 相比,Toolbar 明顯要靈活的多。它不像 Actionbar 一樣,一定要固定在Activity的頂部,而是可以放到界面的任意位置。其支持:

設置導航欄圖標; 設置App的logo; 支持設置標題和子標題; 支持添加一個或多個的自定義控件; 支持Action Menu;

Toolbar 是在 Android 5.0 才開始加上的,如果想向下兼容的話,我們需要在工程中引入 appcompat-v7 的兼容包,使用 android.support.v7.widget.Toolbar 進行開發。

Toolbar在xml文件中的代碼



    
    

其中:background的值的作用是:使其背景色跟隨Activity主題指定的顏色(我是這麼理解的)
android toolbar作為actionbar 在低分辨率手機上高度太高如何解決?(在知乎看到的,並沒有測試)

Activity中的代碼:

toolbar = (Toolbar) findViewById(R.id.toolbar);
toolbar.setNavigationIcon(R.mipmap.ic_launcher);//設置導航欄圖標
//toolbar.setLogo(R.mipmap.ic_launcher);//設置app logo
toolbar.setTitle("Title");//設置主標題
//toolbar.setTitleTextColor(getResources().getColor(R.color.colorAccent));
//setSupportActionBar(toolbar);
//toolbar.setSubtitle("Subtitle");//設置子標題
toolbar.inflateMenu(R.menu.menu_toolbar);//設置右上角的填充菜單
toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
    @Override
    public boolean onMenuItemClick(MenuItem item) {
        int menuItemId = item.getItemId();
        if (menuItemId == R.id.action_search) {
            Toast.makeText(MainActivity.this, "searh", Toast.LENGTH_SHORT).show();
        } else if (menuItemId == R.id.action_share) {
            Toast.makeText(MainActivity.this, "action_share", Toast.LENGTH_SHORT).show();
        } else if (menuItemId == R.id.action_item1) {
            Toast.makeText(MainActivity.this, "action_item1", Toast.LENGTH_SHORT).show();
        } else if (menuItemId == R.id.action_item2) {
            Toast.makeText(MainActivity.this, "action_item2", Toast.LENGTH_SHORT).show();
        }
        return true;
    }
});

(四): NavigationView

在Material Design中,NavigationView導航抽屜,被設計用於應用導航,提供了一種通用的導航方式,體現了設計的一致性。而NavigationView的典型用途就是配合之前v4包的DrawerLayout,作為其中的Drawer部分,即導航菜單的本體部分。NavigationView是一個導航菜單框架,使用menu資源填充數據,使我們可以更簡單高效的實現導航菜單。它提供了不錯的默認樣式、選中項高亮、分組單選、分組子標題、以及可選的Header。
參考博文:http://www.jianshu.com/p/76e30f87a4ed;
Tip:在使用Android Studio 開發的時候創建Activity可以選擇帶NavigationView的Activity,一分鐘就搞定了這個效果,你還瞎折騰啥;

碰到的坑:java.lang.IllegalArgumentException: DrawerLayout must be measured with MeasureSpec.EXACTLY.
這個錯誤是的解決辦法是把DrawerLayout 的父容器寬高設置成match_paren

如何使用:典型的布局文件如下,外層是DrawerLayout,它的第一個child將作為content,第二個child作為Drawer




    

        

        
            
            <framelayout android:background="@color/content_bg" android:id="@+id/content_layout" android:layout_height="match_parent" android:layout_width="match_parent">
            
            
        </framelayout>
    

其中:在DrawerLayout節點添加tools:openDrawer=”start”這個屬性目前發現的作用是在布局的時候能查看到效果,去除的話會使節點下的drawer布局在preview觀察模式下不可見,刪除亦沒有影響
但是NavigationView節點下的android:layout_gravity=”start”這條屬性不可刪除,刪除的後果是drawer布局充滿屏幕,點擊程序異常崩潰 ,且可在此節點下設置drawer布局的背景顏色
NavigationView節點下:這兩條屬性是引用抽屜的頭布局和布局用的
app:headerLayout=”@layout/drawer_header”
app:menu=”@menu/drawer”
這裡寫圖片描述
效果圖如上:這裡我們會看到toolbar的title是默認對應的Activity名稱,如果想更換的話手動設置toolbar.setTitle(“噜噜噜”),並且你也可以看到一個text文本顯示clock,這個就是toolbar自定義的按鈕
抽屜頭布局xml代碼:




    

drawer布局xml


說明:其中節點代表分組,android:checkableBehavior=”single”這個屬性表述這個group子條目只能單選,我們還可以通過為item添加子菜單來實現帶有頭部的分組效果,就像上圖group小組下面item那樣設置,並可以為這個小組設置title;分組是可以選中的,在子 menu item 設置 android:checkable=”true” 就行了
在Activity中的代碼:
Activity中必須實現:implements NavigationView.OnNavigationItemSelectedListener

//獲取控件,設置監聽
NavigationView navigationView = (NavigationView) findViewById(R.id.navigation);
navigationView.setNavigationItemSelectedListener(this);
//設置點擊返回鍵抽屜縮進
@Override
public void onBackPressed() {
    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    if (drawer.isDrawerOpen(GravityCompat.START)) {
        drawer.closeDrawer(GravityCompat.START);
    } else {
        super.onBackPressed();
    }
}
//抽屜裡item的點擊事件
@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected(MenuItem item) {
    // Handle navigation view item clicks here.
    int id = item.getItemId();
    if (id == R.id.navigation_original) {

    } else if (id == R.id.navigation_library) {

    } else if (id == R.id.navigation_component) {

    } else if (id == R.id.navigation_ui) {

    } else if (id == R.id.navigation_text) {

    } else if (id == R.id.nav_send) {

    }
    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    drawer.closeDrawer(GravityCompat.START);
    return true;
}

(五): Palette

compile ‘com.android.support:palette-v7:21.0.+’

Eclipse首先我們找到sdk/extras/android/support/v7/palette/libs/android-support-v7-palette.jar導入我們的工程。

 /**
     * 界面顏色的更改
     */
    private void colorChange(int position) {
        // 用來提取顏色的Bitmap
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(),drawables[position] );
        // Palette的部分
        Palette.generateAsync(bitmap, new Palette.PaletteAsyncListener() {
            /**
             * 提取完之後的回調方法
             */
            @Override
            public void onGenerated(Palette palette) {
                Palette.Swatch vibrant = palette.getVibrantSwatch();
                //設置tabLayout的背景顏色,為palette取出來的顏色
                tabLayout.setBackgroundColor(vibrant.getRgb());
                //設置選中的TabLayout標簽底部游標的顏色為palette取出來的顏色,並且加深顏色
                tabLayout.setSelectedTabIndicatorColor(colorBurn(vibrant.getRgb()));
                //設置tab標簽顏色,第一個參數是未被選中tab標簽顏色,第二個是選中的tab標簽顏色
                tabLayout.setTabTextColors(getResources().getColor(R.color.gray),getResources().getColor(R.color.withe));
                //設置toolbar背景色為palette取出來的顏色
                toolbar.setBackgroundColor(vibrant.getRgb());
                if (android.os.Build.VERSION.SDK_INT >= 21) {
                    Window window = getWindow();
                    // 很明顯,這兩貨是新API才有的。
                    window.setStatusBarColor(colorBurn(vibrant.getRgb()));
                    window.setNavigationBarColor(colorBurn(vibrant.getRgb()));
                }
            }
        });
    }
 /**
     * 顏色加深處理
     *
     * @param RGBValues
     *            RGB的值,由alpha(透明度)、red(紅)、green(綠)、blue(藍)構成,
     *            Android中我們一般使用它的16進制,
     *            例如:"#FFAABBCC",最左邊到最右每兩個字母就是代表alpha(透明度)、
     *            red(紅)、green(綠)、blue(藍)。每種顏色值占一個字節(8位),值域0~255
     *            所以下面使用移位的方法可以得到每種顏色的值,然後每種顏色值減小一下,在合成RGB顏色,顏色就會看起來深一些了
     * @return
     */
    private int colorBurn(int RGBValues) {
        int alpha = RGBValues >> 24;
        int red = RGBValues >> 16 & 0xFF;
        int green = RGBValues >> 8 & 0xFF;
        int blue = RGBValues & 0xFF;
        red = (int) Math.floor(red * (1 - 0.1));
        green = (int) Math.floor(green * (1 - 0.1));
        blue = (int) Math.floor(blue * (1 - 0.1));
        return Color.rgb(red, green, blue);
    }
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved