Android6.0-新控件(一)

来源:互联网 发布:武昌首义学院淘宝地址 编辑:程序博客网 时间:2024/05/10 09:49

[转载请注明出处:http://blog.csdn.net/listeners_Gao/article/details/52886162 —By ListenerGao]

前言

谷歌在2015年I/O大会上发布了Android M的新版本.在这次的I/O大会上,谷歌对Android并没有做很大的改变,主要完善之前的Android L版本.不过这次谷歌在继Material Design风格之后,做了很多风格上的兼容,并推出了Android Design Support Library库,全面支持Material Design设计风格的UI效果.该库包含了FloatingActionButton,TextInputLayout,Snackbar,TabLayout,NavigationView,CoordinatorLayout,AppBarLayout,CollapsingToolbarLayout八个新控件.由于篇幅的原因,我们先来学习一下前四个的使用.后续会继续完成其余控件的使用.

使用

需要导入Android Design Support Library库,该库支持Android 2.1以上设备.在build.gradle(moudle:app)中添加依赖:compile 'com.android.support:design:24.2.1' 版本号可自己匹配.

FloatingActionButton

效果图:

<android.support.design.widget.FloatingActionButton    android:id="@+id/fab_button"    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:layout_gravity="bottom|right"    android:src="@drawable/ic_favorite"    android:layout_margin="10dp"    app:backgroundTint="@color/colorPrimary"    app:elevation="4dp"    app:pressedTranslationZ="8dp"    app:fabSize="normal"    app:rippleColor="@color/colorPrimaryDark"    app:useCompatPadding="false" />

注意:

设置FloatingActionButton的背景颜色时使用:app:backgroundTint,默认为 Theme 主题中的 “colorAccent”的颜色;如果使用android:backgroundTint运行时,则会报解析Xml异常.

设置FloatingActionButton的大小,通过app:fabSize属性来设置,有三种格式:auto(基于窗口的大小而自动适应),normal(正常大小的按钮),mini(迷你大小的按钮).这里设置layout_width和layout_height貌似没有什么效果,FloatingActionButton的大小由fabSize属性来决定.可当你把宽和高设置成match_parent时,FloatingActionButton的大小会充满父窗体,大小虽然改变了,但这样的设置在开发中貌似没一点卵用.

app:elevation :设置 FloatingActionButton 阴影的深度,默认有阴影.

app:pressedTranslationZ :设置 FloatingActionButton 点击时阴影的大小.

app:rippleColor :设置 FloatingActionButton 点击时的颜色,也就是设置上面属性后,阴影的颜色.

app:useCompatPadding :设置是否启用compat的填充.

src - 设置FAB的图标,Google建议符合Design设计的该图标大小为24dp.

app:layout_anchor - 设置FAB的锚点,即以哪个控件为参照点设置位置.

app:layout_anchorGravity - 设置FAB相对锚点的位置,值有 bottom、center、right、left、top等.

以上在Xml布局中设置的属性,在代码中同样可以设置.

Snackbar

  • 简介: Snackbar用于展示一条简短的消息给用户,该消息在很多的时间内会消失.该消息只是给用户一个提示,用户不需要去操作.例如:当我们发送一条Email时,告诉用户该Email发送的状态.Snackbar和Toast很像,只不过Toast是在屏幕中心弹出,而Snackbar是在屏幕底部弹出.

  • 使用:代码中使用

    //得到Snackbar对象final Snackbar snackbar = Snackbar.make(coordinatorLayout, "我是Snackbar...", Snackbar.LENGTH_LONG);//设置Snackbar背景snackbar.getView().setBackgroundResource(R.color.colorPrimary);snackbar.show();//显示带Action的Snackbarsnackbar.setAction("取消", new View.OnClickListener() {    @Override    public void onClick(View v) {        //关闭Snackbar        snackbar.dismiss();    }});
  • 常用方法:

    • make() 方法,生成Snackbar消息对象,第一个参数为View对象,Snackbar 会试着寻找一个父 View 来 hold 这个 View。Snackbar 将遍历整个 View tree 来寻找一个合适的父 View,它可能是一个 coordinatorLayout 也可能是 window decor’s content view,随便哪一个都行.后面的两个参数和Toast一致.
    • setDuration() 方法:设置显示持续时间.
    • setAction() 方法:设置 Action,第一个参数会作为按钮(Actiong)的文本,第二个参数是按钮的点击事件.
    • setCallback() 方法:Snackbar 的显示和消失会回调 Snackbar.Callback的 onDismissed()和 onShown()方法.
    • getView():获取 Snackbar 的 View,进而可以定制Snackbar.
  • 注意:

    • 谷歌其实更建议在CoordinatorLayout(不要着急,后面会细说)布局中使用Snackbar(make()方法中传入的View),当用户滑动屏幕时,可以使Snackbar消失.
    • 当然,如果你只是想在底部弹出提示消息,那么make()方法中传入的任意的View即可.
    • 还有就是当你点击FloatingActionButton时,想弹出Snackbar,同时又想避免Snackbar遮盖住FloatingActionButton,这时,你应该使用CoordinatorLayout来协调各个View之间的动画效果.

效果图:设置点击FloatingActionButton的点击事件,点击弹出Snackbar.

TextInputLayout

  • 简介: TextInputLayout的出现是Google为EditText提供的浮动标签,使其更符合Material Design的风格.TextInputLayout继承LinearLayout,它只是一个容器,不过该容器下只接收一个元素,子元素就是一个EditText元素.这样就为EditText提供了一个带有动画效果的提示标签,同时也可以处理错误信息,将错误信息提示在EditText的下方.

  • 使用:

    • 布局:

      <android.support.design.widget.TextInputLayout        android:id="@+id/til_username"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_marginLeft="30dp"        android:layout_marginRight="30dp"        android:layout_marginTop="20dp">    <!--这里可以直接使用EditText-->    <android.support.design.widget.TextInputEditText            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:hint="Username" /></android.support.design.widget.TextInputLayout><android.support.design.widget.TextInputLayout    android:id="@+id/til_password"    android:layout_width="match_parent"    android:layout_height="wrap_content"    android:layout_marginLeft="30dp"    android:layout_marginRight="30dp"    android:layout_marginTop="10dp">        <android.support.design.widget.TextInputEditText            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:hint="Password"            android:inputType="textPassword" /></android.support.design.widget.TextInputLayout>
    • 代码:

      //初始化TextInputLayout(代码中我使用了ButterKnife注解,这里就不贴出来了)//得到EditText对象final EditText userEditText = tilUsername.getEditText();final EditText pwdEditText = tilPassword.getEditText();//设置hint提示,也可直接在xml中设置(个人感觉如果在布局中已经设置了hint,代码中就不必在设置了.)//userEditText.setHint("Username");//pwdEditText.setHint("Password");//EditText添加文本变化监听userEditText.addTextChangedListener(new TextWatcher() {    @Override    public void beforeTextChanged(CharSequence s, int start, int count, int after) {        Log.d(TAG, "beforeTextChanged执行了....s = " + s + "---start = " + start + "---count = " + count + "---after = " + after);    }    @Override    public void onTextChanged(CharSequence s, int start, int before, int count) {        Log.d(TAG, "onTextChanged执行了....s = " + s + "---start = " + start + "---count = " + count + "---before = " + before);        if (s.length() > 7) {            tilUsername.setErrorEnabled(true);//设置是否打开错误提示            tilUsername.setError("用户名长度不能超过8个");//设置错误提示的信息        } else {            tilUsername.setErrorEnabled(false);        }    }    @Override    public void afterTextChanged(Editable s) {        Log.d(TAG, "afterTextChanged执行了....s = " + s);    }    });pwdEditText.addTextChangedListener(new TextWatcher() {    @Override    public void beforeTextChanged(CharSequence s, int start, int count, int after) {    }    @Override    public void onTextChanged(CharSequence s, int start, int before, int count) {        if (s.length() < 6) {            tilPassword.setErrorEnabled(true);            tilPassword.setError("密码长度不能小于6个");        } else {            tilPassword.setErrorEnabled(false);        }    }    @Override    public void afterTextChanged(Editable s) {    }});
  • 注意:代码里注释已经很详细了,相信你一看就能明白.这里提一点:就是浮动标签字体的颜色默认是你设置主题时的颜色.

    设置主题的颜色就是EditText浮动标签提示信息的颜色:<item name="colorAccent">@color/colorAccent</item>

效果图:这里模拟登录界面。并对用户名长度是否超过8个,密码长度是否小于6个做了判断。

TabLayout

  • 简介: TabLayout提供了一个水平布局显示标签,主要用来做选显卡切换这一类效果的控件。例如:网易新闻客户端的Tab。Github上也有很多类似效果的开源控件,只是这次谷歌把它官方化了,更方便开发者使用。
  • 简单TabLayout效果图:

  • 使用:

    • xml:

      <android.support.design.widget.TabLayout    android:id="@+id/tab_layout"    android:layout_width="match_parent"    android:layout_height="wrap_content"    app:tabIndicatorColor="@android:color/holo_blue_bright"     //Tab指示器下标的颜色    app:tabSelectedTextColor="@android:color/holo_blue_bright"  //Tab被选中字体的颜色    app:tabTextColor="@android:color/black">                    //Tab未被选中字体的颜色</android.support.design.widget.TabLayout>
    • 代码:

      //添加8个Tab标签,并设置第一个Tab标签为选中状态.tabLayout.addTab(tabLayout.newTab().setText("Tab 1"),true);tabLayout.addTab(tabLayout.newTab().setText("Tab 2"));tabLayout.addTab(tabLayout.newTab().setText("Tab 3"));tabLayout.addTab(tabLayout.newTab().setText("Tab 4"));tabLayout.addTab(tabLayout.newTab().setText("Tab 5"));tabLayout.addTab(tabLayout.newTab().setText("Tab 6"));tabLayout.addTab(tabLayout.newTab().setText("Tab 7"));tabLayout.addTab(tabLayout.newTab().setText("Tab 8"));//设置Tab的模式为可滑动,当tab标签超过屏幕宽度时,可以滑动.tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);

    这里只是简单使用TabLayout完成Tabs选项卡,一般情况下TabLayout+ViewPager相结合使用,这样的使用场景会更多一点,也能发挥出TabLayout的优势。接下来使用TabLayout+ViewPager完成一个小Demo。

  • 效果图:(自定义TabLayout样式+ViewPager使用)

  • 使用:首先我们在Style中自定义TabLayout的样式,在布局中使用时引入自定义的TabLayout样式.添加ViewPager,每个页面是一个Fragment,并且实现联动效果,下面直接看代码:

    • 自定义TabLayout样式:

      <!-- 自定义 TabLayout 样式 --><style name="CustomTabLayout" parent="Widget.Design.TabLayout">    <item name="paddingEnd">10dp</item>    <item name="paddingStart">10dp</item>    <item name="tabBackground">@color/colorPrimary</item>    <item name="tabContentStart">10dp</item>    <item name="tabGravity">center</item>    <item name="tabIndicatorColor">#999900</item>    <item name="tabIndicatorHeight">6dp</item>    <item name="tabMaxWidth">@dimen/tab_max_width</item>    <item name="tabMinWidth">@dimen/tab_min_width</item>    <item name="tabMode">scrollable</item>    <item name="tabPaddingBottom">2dp</item>    <item name="tabPaddingEnd">10dp</item>    <item name="tabPaddingStart">10dp</item>    <item name="tabPaddingTop">15dp</item>    <item name="tabSelectedTextColor">#ffcc00</item>    <item name="tabTextAppearance">@style/CustomTabTextAppearance</item>    <item name="tabTextColor">#000066</item></style><!-- 自定义 TabText 的外观 --><style name="CustomTabTextAppearance" parent="TextAppearance.Design.Tab">    <item name="android:textSize">14sp</item>    <item name="android:textColor">#006600</item>    <item name="textAllCaps">false</item></style>
    • 页面布局:

      <?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:id="@+id/activity_tab_layout_view_pager"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"    tools:context="com.listenergao.mytest.activity.TabLayoutViewPagerActivity">    <include layout="@layout/toolbar_layout" />    <android.support.design.widget.TabLayout        android:id="@+id/tab_layout"        style="@style/CustomTabLayout"        android:layout_width="match_parent"        android:layout_height="wrap_content">    </android.support.design.widget.TabLayout>    <android.support.v4.view.ViewPager        android:id="@+id/viewpager"        android:layout_width="match_parent"        android:layout_height="match_parent">    </android.support.v4.view.ViewPager></LinearLayout>
    • 页面代码:(Activity页面)

      package com.listenergao.mytest.activity;import android.os.Bundle;import android.support.design.widget.TabLayout;import android.support.v4.app.Fragment;import android.support.v4.view.ViewPager;import android.support.v7.widget.Toolbar;import android.widget.LinearLayout;import com.listenergao.mytest.R;import com.listenergao.mytest.data.TabFragmentAdapter;import com.listenergao.mytest.fragment.TabFragment;import java.util.ArrayList;import java.util.List;import butterknife.BindView;import butterknife.ButterKnife;/** * TabLayout+ViewPager示例 * * @author By ListenerGao *         create at 2016/10/14 18:52 */public class TabLayoutViewPagerActivity extends BaseActivity {    @BindView(R.id.toolbar)    Toolbar toolbar;    @BindView(R.id.tab_layout)    TabLayout tabLayout;    @BindView(R.id.viewpager)    ViewPager viewpager;    @BindView(R.id.activity_tab_layout_view_pager)    LinearLayout activityTabLayoutViewPager;    private List<String> mTabList;    private List<Fragment> mTabFragments;    @Override    protected int getLayoutResId() {        return R.layout.activity_tab_layout_view_pager;    }    @Override    protected void initView() {        ButterKnife.bind(this);        toolbar.setTitle("TabLayout+ViewPager");        setSupportActionBar(toolbar);        getSupportActionBar().setDisplayHomeAsUpEnabled(true);    }    @Override    protected void initData() {        mTabList = initTabList();        initTabLayout(mTabList);        mTabFragments = initFragments(mTabList);        TabFragmentAdapter adapter = new TabFragmentAdapter(getSupportFragmentManager(),mTabFragments,mTabList);        viewpager.setAdapter(adapter);        //将TabLayout与ViewPager关联起来(注意:该行代码需在ViewPager设置Adapter之后调用)        tabLayout.setupWithViewPager(viewpager);        //为Tabs设置适配器        tabLayout.setTabsFromPagerAdapter(adapter);    }    /**     * 初始化Tab标签数据     *     * @return     */    private List<String> initTabList() {        List<String> tabList = new ArrayList<>();        for (int i = 0; i < 8; i++) {            tabList.add("TAB " + i);        }        return tabList;    }    /**     * 初始化TabLayout     *     * @param list     */    private void initTabLayout(List<String> list) {        for (int i = 0; i < list.size(); i++) {            if (i == 0)                tabLayout.addTab(tabLayout.newTab().setText(list.get(i)), true);            else                tabLayout.addTab(tabLayout.newTab().setText(list.get(i)));        }        //设置TabLayout的模式为可滑动        tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);    }    /**     * 初始化Tab标签对应的Fragment     *     * @param list 标签集合数据     * @return     */    public List<Fragment> initFragments(List<String> list) {        List<Fragment> mTabFragments = new ArrayList<>();        for (int i = 0; i < list.size(); i++) {            Fragment tabFragment = new TabFragment();            Bundle bundle = new Bundle();            bundle.putString("Content", list.get(i));            tabFragment.setArguments(bundle);            mTabFragments.add(tabFragment);        }        return mTabFragments;    }}
    • Viewpager适配器:(这里继承的是FragmentStatePagerAdapter,因为可能有很多个Tab标签页面(Fragment).这里不细说,可以自行google.)

      package com.listenergao.mytest.data;import android.support.v4.app.Fragment;import android.support.v4.app.FragmentManager;import android.support.v4.app.FragmentStatePagerAdapter;import java.util.List;/** * ViewPager的适配器 * * @author By ListenerGao *         Create at 2016/10/15 16:36 */public class TabFragmentAdapter extends FragmentStatePagerAdapter {    private List<Fragment> mFragments;    private List<String> mTabTitles;    public TabFragmentAdapter(FragmentManager fm, List<Fragment> fragments,List<String> tabTitles) {        super(fm);        this.mFragments = fragments;        this.mTabTitles = tabTitles;    }    @Override    public Fragment getItem(int position) {        return mFragments.get(position);    }    @Override    public int getCount() {        return mFragments.size();    }    //注意:需要重写此方法,从标签集合中获取到title,否则标签上的title则不会显示.    @Override    public CharSequence getPageTitle(int position) {        return mTabTitles.get(position);    }}
    • Tab标签对应的Fragment页面:

      package com.listenergao.mytest.fragment;import android.os.Bundle;import android.support.annotation.Nullable;import android.support.v4.app.Fragment;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.TextView;import com.listenergao.mytest.R;import butterknife.BindView;import butterknife.ButterKnife;/** * Tab标签对应的页面 * * @author By ListenerGao *         Create at 2016/10/15 16:53 */public class TabFragment extends Fragment {    @BindView(R.id.tv_content)    TextView tvContent;    private View view;    private String content;    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        if (getArguments() != null) {            Bundle bundle = getArguments();            content = bundle.getString("Content");        }    }    @Override    public View onCreateView(LayoutInflater inflater, ViewGroup container,                             Bundle savedInstanceState) {        // Inflate the layout for this fragment        view = inflater.inflate(R.layout.fragment_tab, container, false);        ButterKnife.bind(this, view);        return view;    }    @Override    public void onActivityCreated(@Nullable Bundle savedInstanceState) {        super.onActivityCreated(savedInstanceState);        tvContent.setText(content);    }}
  • 常用方法:

    • 1,addTab(TabLayout.Tab tab, int position, boolean setSelected) 增加选项卡到 layout中,这是一个重载方法.第一个参数是Tab对象,通过Tablayout.newTab()创建;第二个参数是插入Tab的位置;最后一个参数是当前Tab是否为选中状态.
    • 2,newTab() 新建个 tab.
    • 3,setTabMode(),设置 Mode,有两种值:TabLayout.MODE_SCROLLABLE和TabLayout.MODE_FIXED分别表示当tab的内容超过屏幕宽度是否支持横向水平滑动,第一种支持滑动,第二种不支持,默认不支持水平滑动.如果你添加的Tab很少的话,你应该把Tab的mode设置成MODE_FIXED,否则可能会出现Tab标签不会占满屏幕的宽度.
    • 4,setOnTabSelectedListener(TabLayout.OnTabSelectedListener onTabSelectedListener) 为每个 tab 增加选择监听器.
    • 5,setScrollPosition(int position, float positionOffset, boolean updateSelectedText) 设置Tab滚动到的位置.
    • 6,setTabGravity(int gravity) 设置 Gravity.
    • 7,setTabTextColors(ColorStateList textColor) 设置 tab 中文本的颜色.
    • 8,setTabTextColors(int normalColor, int selectedColor) 设置 tab 中文本的颜色 默认 选中的颜色.
    • 9,setTabsFromPagerAdapter(PagerAdapter adapter) 将TabLayout与ViewPager关联,当PageAdapter更新时,TabLayout会自动更新.(注意:该方法已过时)
    • 10,setupWithViewPager(ViewPager viewPager) 设置Tablayout和ViewPager实现联动效果.
    • 11,getTabAt(int index) 得到选项卡.
    • 12,getTabCount() 得到选项卡的总个数.
    • 13,getTabGravity() 得到 tab 的 Gravity.
    • 14,getTabMode() 得到 tab 的模式.
    • 15,getTabTextColors() 得到 tab 中文本的颜色.

由于篇幅原因,NavigationView,CoordinatorLayout,AppBarLayout,CollapsingToolbarLayout会在下篇文章中介绍.

源码地址:(该功能是在我一个练手项目中写的)

https://github.com/ListenerGao/MyTest/blob/master/app/src/main/java/com/listenergao/mytest/activity/Android6NewWidget.java

0 0
原创粉丝点击