笔记:MaterialDesign(一)--控/组件简单使用

忘了贴图 copy代码运行看效果

一、TabLayout+ViewPager+Fragment

1.1、MainActivity.java中使用
public class MainActivity extends AppCompatActivity {

    private TabLayout mTabLayout;
    private ViewPager mViewPager;
    private LinearLayout mLinearLayout;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mTabLayout = (TabLayout) findViewById(R.id.tabLayout);
        mViewPager = (ViewPager) findViewById(R.id.viewPager);
        /**
         * 将TabLayout与ViewPager结合
         *
         */
        //步骤一:给VIewPager设置Adapter(FragmentPagerAdapter)
        MyViewPagerAdapter adapter = new MyViewPagerAdapter(getSupportFragmentManager());
        mViewPager.setAdapter(adapter);

        /**
         * 步骤二(到了步骤二可以看效果了,后面步骤是设置indicator属性等代码)
         *
         * 很牛逼的一个方法
         *
         * 关联TabLayout与ViewPager,互相绑定,且适配器必须重写getPageTitle()方法
         *
         * 这个方法三个作用
         *                               1、从ViewPager中获取TabLayout的Title----getPageTitle()
         *                               2、ViewPager滑动时,设置TabLayout的Title和indicator
         *                               3、点击TabLayout时,ViewPager相应变化
         */
        mTabLayout.setupWithViewPager(mViewPager);

        //步骤三   设置分割线:参考https://www.jianshu.com/p/bbefb97cccdd
        mLinearLayout = (LinearLayout) mTabLayout.getChildAt(0);
        // 在所有子控件的中间显示分割线(还可 只显示顶部、尾部和不显示分割线)
        mLinearLayout.setShowDividers(LinearLayout.SHOW_DIVIDER_MIDDLE);
        // 设置分割线的距离本身(LinearLayout)的内间距
        mLinearLayout.setDividerPadding(50);
        // 设置分割线的样式
        mLinearLayout.setDividerDrawable(ContextCompat.getDrawable(this, R.drawable.divider_vertical));
        mLinearLayout.setBackgroundColor(getResources().getColor(R.color.colorPrimaryDark));


        //步骤四   设置指示器的长度(本来是不可设置的),这里是通过Tab外间距的方式
        // 自定义指示器(Indicator)的“长度”的两种方法,会有跳动的bug情况未解决,不推荐使用只做为一种示例
        // 方法一:反射
//                setIndicator(mTabLayout,10,10);
        // 方法二:查找子控件
        int left = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10, Resources.getSystem().getDisplayMetrics());
        int right = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10, Resources.getSystem().getDisplayMetrics());
        for (int i = 0; i < mLinearLayout.getChildCount(); i++) {
            View tabView = mLinearLayout.getChildAt(i);
            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT, 1);
            params.leftMargin = left;
            params.rightMargin = right;
            tabView.setLayoutParams(params);
        }
    }


    public void setIndicator(TabLayout tabs, int leftDip, int rightDip) {
        Class tabLayout = tabs.getClass();
        Field tabStrip = null;//java.lang.reflect.Field
        try {
            tabStrip = tabLayout.getDeclaredField("mTabStrip");
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }

        tabStrip.setAccessible(true);
        LinearLayout llTab = null;
        try {
            llTab = (LinearLayout) tabStrip.get(tabs);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

        int left = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, leftDip, Resources.getSystem().getDisplayMetrics());
        int right = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, rightDip, Resources.getSystem().getDisplayMetrics());

        for (int i = 0; i < llTab.getChildCount(); i++) {
            View child = llTab.getChildAt(i);
            child.setPadding(0, 0, 0, 0);
            LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.MATCH_PARENT, 1);
            params.leftMargin = left;
            params.rightMargin = right;
            child.setLayoutParams(params);
            child.invalidate();
        }
    }


    //步骤一(1)
    private class MyViewPagerAdapter extends FragmentPagerAdapter {

        //步骤一(1)、②  数据
        private final String[] title = new String[]{
                "推荐", "热点", "视频", "图片", "新闻",
                "汽车", "科技","财经", "游戏", "广州","旅游"};


        public MyViewPagerAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public Fragment getItem(int position) {
            //步骤一(1)、③  实例化fragment

            Fragment fragment = new TextFragment();
            //给fragment传数据
            Bundle bundle = new Bundle();
            bundle.putString("title", title[position]);
            fragment.setArguments(bundle);
            return fragment;
        }

        @Override
        public int getCount() {
            return title.length;
        }

        //步骤一(1)、①  实例化fragment
        @Override
        public CharSequence getPageTitle(int position) {
            return title[position];
        }
    }
}
1.2、在activity_main.xml中



    

    

    



二、ListPopupWindow

2.1、在MainActivity.java中
public class MainActivity extends AppCompatActivity {

    private ListPopupWindow mListPopupWindow;
    private ArrayAdapter mAdapter;
    private String[] mItemArr;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mItemArr = new String[]{"test 1", "test 2", "test 3", "test 4", "test 5", "test 6", "test 7", "test 8"};
        mAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, mItemArr);

    }

    public void showPopupWindow(View view){
        if (mListPopupWindow == null)
            mListPopupWindow = new ListPopupWindow(this);
        //应该是 设置 ListPopupWindow 的数据适配器
        mListPopupWindow.setAdapter(mAdapter);
        //应该是 设置 ListPopupWindow 的显示位置(在指定控件下方)
        mListPopupWindow.setAnchorView(view);
        //应该是 设置上下边距的距离
        mListPopupWindow.setVerticalOffset(10);
        //应该是 设置 ListPopupWindow 的宽度
        mListPopupWindow.setWidth(300);
        //应该是 设置 ListPopupWindow 的高度
        mListPopupWindow.setHeight(600);
        //应该是 设置 ListPopupWindow 的条目点击事件(必须在show方法前设置,否则无效)
        mListPopupWindow.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView parent, View view, int position, long id) {
                Toast.makeText(getApplicationContext(), mItemArr[position], Toast.LENGTH_SHORT).show();
                mListPopupWindow.dismiss();
            }
        });
        mListPopupWindow.show();
    }
2.2、在 activity_main.xml 中


    

三、PopupMenu的简单使用

3.1、在MainActivity.java中
 public void showPopupMenu(View view) throws NoSuchFieldException, IllegalAccessException {
        PopupMenu popupMenu = new PopupMenu(this, view);
        //设置 PopupMenu 的显示菜单项
        popupMenu.inflate(R.menu.main);
        // popupMenu.getMenuInflater().inflate(R.menu.main, popupMenu.getMenu());//上一行与这一行效果一样
        //默认 PopupMenu 不显示条目icon,可以通过反射来强制使其显示icon
        Field field = popupMenu.getClass().getDeclaredField("mPopup");
        field.setAccessible(true);
        MenuPopupHelper mHelper = (MenuPopupHelper) field.get(popupMenu);
        mHelper.setForceShowIcon(true);
        //设置 PopupMenu 的条目点击事件(点击后会自动dismiss)
        popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(MenuItem item) {
                Toast.makeText(getApplicationContext(), item.getTitle(), Toast.LENGTH_SHORT).show();
                return false;
            }
        });
        //显示 PopupMenu
        popupMenu.show();
    }
3.2、在 activity_main.xml 中


    
3.3、main.xml 资源(res/menu/main.xml)


    
    
    


四、LinearLayoutCompat的简单使用

4.1、在MainActivity.java中

public class MainActivity extends AppCompatActivity {

    private LinearLayoutCompat linearLayoutCompat;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        linearLayoutCompat = (LinearLayoutCompat) findViewById(R.id.linearLayoutCompat);
    }

    //布局的前面一个分割线
    public void beginning(View view) {
        linearLayoutCompat.setShowDividers(LinearLayoutCompat.SHOW_DIVIDER_BEGINNING);
    }
    //布局的除了前面和后面没有分割线,中间控件之间都有分割线
    public void middle(View view) {
        linearLayoutCompat.setShowDividers(LinearLayoutCompat.SHOW_DIVIDER_MIDDLE);
    }
    //布局的尾部一个分割线
    public void end(View view) {
        linearLayoutCompat.setShowDividers(LinearLayoutCompat.SHOW_DIVIDER_END);
    }
    //布局的除了尾部没有分割线,其他有(前面和中间)
    public void beginning_middle(View view) {
        linearLayoutCompat.setShowDividers(LinearLayoutCompat.SHOW_DIVIDER_BEGINNING | LinearLayoutCompat.SHOW_DIVIDER_MIDDLE);

    }
    //布局的除了前面没有分割线,其他有(中间和后面)
    public void end_middle(View view) {
        linearLayoutCompat.setShowDividers(LinearLayoutCompat.SHOW_DIVIDER_MIDDLE | LinearLayoutCompat.SHOW_DIVIDER_END);
    }

}
4.2、在 activity_main.xml 中



    

        

五、RecyclerView.ItemDecoration 条目item装饰 的简单使用

①、水平/垂直分割线
②、网格布局分割线
③、侧边字母提示样式
④、悬浮头布局样式

5.1、水平/垂直 分割线 装饰

5.1.1、在MainActivity.java中
public class MainActivity extends AppCompatActivity {

    private List mData = new ArrayList<>();
    private RecyclerView mRv;
    private MyAdapter mMyAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mRv = (RecyclerView) findViewById(R.id.rv);

        initDecoration();
        initData();
        initRecyclerView();

    }

    //初始化修饰布局(分割线)
    private void initDecoration() {
        MyDecorationOne decorationOne = new MyDecorationOne(this, LinearLayoutManager.VERTICAL);
        mRv.addItemDecoration(decorationOne);
    }

    //初始化数据
    private void initData() {
        for (int i = 0; i < 100; i++) {
            mData.add("item " + i);
        }
    }

    //初始化recyclerview,关联adapter
    private void initRecyclerView() {
        mMyAdapter = new MyAdapter(mData);
        mRv.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
        mRv.setAdapter(mMyAdapter);
    }

}
5.1.2、在activity_main.xml中



    


5.1.3、自定义装饰 MyDecorationOne.java
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.support.v7.widget.RecyclerView;
import android.view.View;

/**
 * Created by ${chenyuexueer} on 2018/5/9.
 * 

* 说明:自定义recyclerview的自定义条目装饰(分割线,当然它不仅仅可以作为分割线) * * 1、继承RecyclerView.ItemDecoration, * 重写 public void onDraw()和 public void getItemOffsets()方法(并不是必须,可不要) * * 2、构造方法,初始化属性等 * * 3、设计绘图方法 */ public class MyDecorationOne extends RecyclerView.ItemDecoration { int orientation = RecyclerView.VERTICAL;//默认垂直 private final Drawable mDivider; public MyDecorationOne(Context context, int orientation) { this.orientation = orientation;//初始化recyclerview布局方向,activity传过来的recyclerview的布局方向 int[] attrs = new int[]{android.R.attr.listDivider};//系统提供的属性 TypedArray a = context.obtainStyledAttributes(attrs);//属性组 mDivider = a.getDrawable(0);//取组中第一个 a.recycle();//回收 } @Override public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) { super.onDraw(c, parent, state); int childCount = parent.getChildCount();//recyclerview的子item的条数 if (orientation == RecyclerView.HORIZONTAL) {//activity那边设置是水平布局,则绘制一个个垂直()装饰 drawVertical(c, parent,childCount); } else if (orientation == RecyclerView.VERTICAL) {//activity那边设置是水平布局,则绘制一个个垂直装饰 drawHorizontal(c, parent,childCount); } } //绘制垂直装饰 private void drawVertical(Canvas c, RecyclerView parent, int childCount) { for (int i = 0; i < childCount; i++) { View child = parent.getChildAt(i);//第i条item的view对象 //第i条item的view对象的布局参数 RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams(); //计算装饰(分割线)的绘制参数(边距) int left = child.getRight() + params.rightMargin; int top = child.getTop() - params.topMargin; int right = left + mDivider.getIntrinsicWidth(); int bottom = child.getBottom() + params.bottomMargin; //设置装饰(分割线)边距 mDivider.setBounds(left, top, right, bottom); //开始绘制 mDivider.draw(c); } } //绘制水平装饰 private void drawHorizontal(Canvas c, RecyclerView parent, int childCount) { for (int i = 0; i < childCount; i++) { View child = parent.getChildAt(i); RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams(); int left = child.getLeft() - params.leftMargin; int top = child.getBottom() + params.bottomMargin; int right = child.getRight() + params.rightMargin; int bottom = top + mDivider.getIntrinsicHeight(); mDivider.setBounds(left, top, right, bottom); mDivider.draw(c); } } /** * 设置条目周边的偏移量(即偏移分割线的大小距离) */ @Override public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { super.getItemOffsets(outRect, view, parent, state); if (orientation == RecyclerView.HORIZONTAL) { //画垂直线 outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0); } else if (orientation == RecyclerView.VERTICAL) { //画水平线 outRect.set(0, 0, 0, mDivider.getIntrinsicHeight()); } }

5.1.4、MyAdapter.java
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;

import java.util.List;

public class MyAdapter extends RecyclerView.Adapter {

    private List mData;

    public MyAdapter(List data) {
        mData = data;
    }

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View itemView = View.inflate(parent.getContext(), android.R.layout.simple_list_item_1, null);
        itemView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
        return new MyViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        holder.mTv.setText(mData.get(position));
    }

    @Override
    public int getItemCount() {
        return mData.size();
    }

    class MyViewHolder extends RecyclerView.ViewHolder {

        TextView mTv;

        public MyViewHolder(View itemView) {
            super(itemView);
            mTv = (TextView) itemView.findViewById(android.R.id.text1);
        }
    }

}

5.2、网格分割 装饰

5.2.1、MainActivity.java
public class MainActivity extends AppCompatActivity {

    private List mData = new ArrayList<>();
    private RecyclerView mRv;
    private MyAdapter mMyAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mRv = (RecyclerView) findViewById(R.id.rv);

        initDecoration();
        initData();
        initRecyclerView();

    }

    //初始化修饰布局(分割线)
    private void initDecoration() {
        MyDecorationTwo decorationTwo = new MyDecorationTwo(this);
        mRv.addItemDecoration(decorationTwo);
    }

    //初始化数据
    private void initData() {
        for (int i = 0; i < 100; i++) {
            mData.add("item " + i);
        }
    }

    //初始化recyclerview,关联adapter,这里使用GridLayoutManager表格布局
    private void initRecyclerView() {
        mMyAdapter = new MyAdapter(mData);
        mRv.setLayoutManager(new GridLayoutManager(this, 4));
        mRv.setAdapter(mMyAdapter);
    }

}
5.2.2、activity_main.xml

具体代码----同上(5.1.2、activity_main.xml)

5.2.3、 MyAdapter.java

具体代码----同上(5.1.4、MyAdapter.java)

5.2.4、自定义装饰 MyDecorationTwo.java
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;

/**
 * Created by ${chenyuexueer} on 2018/5/9.
 * 

* 说明:自定义recyclerview的自定义条目装饰(网格分割) * * 1、构造方法,初始化属性等 * * 2、继承RecyclerView.ItemDecoration, * 重写 public void onDraw()和 public void getItemOffsets()方法 * public void getItemOffsets()方法并不是必须,可不用(没有节点),可以注释掉这个方法看效果 * * 3、设计绘图方法 */ public class MyDecorationTwo extends RecyclerView.ItemDecoration { private final Drawable mDivider; public MyDecorationTwo(Context context) {//构造方法初始化数据 //与MyDecorationOne相比,这里是自定义的资源文件,MyDecorationOne是系统提供的资源文件 mDivider = context.getResources().getDrawable(R.drawable.divider); } @Override public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) { super.onDraw(c, parent, state); int childCount = parent.getChildCount();//recyclerview的子item的条数 //水平垂直都要绘制分割线,这样才能形成网格 drawVertical(c, parent,childCount); drawHorizontal(c, parent,childCount); } //绘制垂直装饰 private void drawVertical(Canvas c, RecyclerView parent, int childCount) { for (int i = 0; i < childCount; i++) { View child = parent.getChildAt(i);//第i条item的view对象 //第i条item的view对象的布局参数 RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams(); //计算装饰(分割线)的绘制参数(边距) int left = child.getRight() + params.rightMargin; int top = child.getTop() - params.topMargin; int right = left + mDivider.getIntrinsicWidth(); int bottom = child.getBottom() + params.bottomMargin; //设置装饰(分割线)边距 mDivider.setBounds(left, top, right, bottom); //开始绘制 mDivider.draw(c); } } //绘制水平装饰 private void drawHorizontal(Canvas c, RecyclerView parent, int childCount) { for (int i = 0; i < childCount; i++) { View child = parent.getChildAt(i); RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams(); int left = child.getLeft() - params.leftMargin; int top = child.getBottom() + params.bottomMargin; int right = child.getRight() + params.rightMargin; int bottom = top + mDivider.getIntrinsicHeight(); mDivider.setBounds(left, top, right, bottom); mDivider.draw(c); } } /** * 设置条目右下边的偏移量(效果:右下边有一个空白的小正方形节点) */ @Override public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) { super.getItemOffsets(outRect, itemPosition, parent); //getIntrinsicWidth()/getIntrinsicHeight()与getWidth()/getHeight()区别具体请自行百度谷歌 int right = mDivider.getIntrinsicWidth(); int bottom = mDivider.getIntrinsicHeight(); //第itemPosition个条目item的最后一列,即正方形的下边,则不需要绘制右边 if (isLastSpan(itemPosition, parent)) { right = 0; } //第itemPosition个条目item的最后一行,即正方形的右边,则不需要绘制底部 if (isLastRow(itemPosition, parent)) { bottom = 0; } outRect.set(0, 0, right, bottom); } public boolean isLastRow(int itemPosition, RecyclerView parent) { RecyclerView.LayoutManager layoutManager = parent.getLayoutManager(); if (layoutManager instanceof GridLayoutManager) { int spanCount = ((GridLayoutManager) layoutManager).getSpanCount(); int itemCount = parent.getAdapter().getItemCount(); if ((itemCount - itemPosition - 1) < spanCount)//则不需要底部 return true; } return false; } public boolean isLastSpan(int itemPosition, RecyclerView parent) { RecyclerView.LayoutManager layoutManager = parent.getLayoutManager(); if (layoutManager instanceof GridLayoutManager) { int spanCount = ((GridLayoutManager) layoutManager).getSpanCount(); if ((itemPosition + 1) % spanCount == 0)//则不需要绘制右边 return true; } return false; } }

5.2.4、divider.xml 资源文件 res/drawable/divider.xml



    
    


5.3、侧边字母提示 装饰

需要依赖 拼音工具包
sourceforge 开源项目jar包
Github 依赖

5.3.1、MainActivity.java
public class MainActivity extends AppCompatActivity {

    private List mData = new ArrayList<>();
    private RecyclerView mRv;
    private MyAdapter mMyAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mRv = (RecyclerView) findViewById(R.id.rv);

        initData();
        initDecoration();
        initRecyclerView();

    }

    //初始化修饰布局(首字母提示)
    private void initDecoration() {
        MyDecorationThree decorationThree = new MyDecorationThree(this, mData);
        mRv.addItemDecoration(decorationThree);
    }

    //初始化数据
    private void initData() {
        mData = Arrays.asList(Cheeses.NAMES);
        //系统方法     排序
        Collections.sort(mData, new Comparator() {
            @Override
            public int compare(String o1, String o2) {
                return PinyinUtils.getPinyin(o1).compareTo(PinyinUtils.getPinyin(o2));
            }
        });
    }

    //初始化recyclerview,关联adapter
    private void initRecyclerView() {
        mMyAdapter = new MyAdapter(mData);
        mRv.setLayoutManager(new LinearLayoutManager(this));
        mRv.setAdapter(mMyAdapter);
    }

}
5.3.2、拼音工具 PinyinUtils.java
/**
 * Created by ${chenyuexueer} 
 * 
 * 说明:拼音工具(需要依赖或者导入pinyin4j-2.5.0.jar)
 */

public class PinyinUtils {

    /**
     * 根据传入的字符串(包含汉字),得到拼音
     * 如:
     *
     * 好学 -> HAOXUE
     * 好 学*& -> HAOXUE
     * 好学y2 -> HAOXUE
     *
     * @param str 字符串
     * @return
     */
    public static String getPinyin(String str) {

        HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();
        format.setCaseType(HanyuPinyinCaseType.UPPERCASE);
        format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);

        StringBuilder sb = new StringBuilder();

        char[] charArray = str.toCharArray();
        for (int i = 0; i < charArray.length; i++) {
            char c = charArray[i];
            // 如果是空格, 跳过
            if (Character.isWhitespace(c)) {
                continue;
            }
            if (c >= -127 && c < 128 || !(c >= 0x4E00 && c <= 0x9FA5)) {
                // 满足条件 ,则肯定不是汉字
                sb.append(c);
            } else {
                String s = "";
                try {
                    // 通过char得到拼音集合. 单 -> dan, shan
                    s = PinyinHelper.toHanyuPinyinStringArray(c, format)[0];
                    sb.append(s);
                } catch (BadHanyuPinyinOutputFormatCombination e) {
                    e.printStackTrace();
                    sb.append(s);
                }
            }
        }

        return sb.toString();
    }

}
5.3.3、自定义修饰类 MyDecorationThree .java
/**
 * Created by ${chenyuexueer} 
 * 

* 说明: */ public class MyDecorationThree extends RecyclerView.ItemDecoration { Context mContext; List mData; Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);//画笔 public MyDecorationThree(Context context, List data) { mContext = context; mData = data; //画笔字体大小与颜色 paint.setTextSize(sp2px(16)); paint.setColor(Color.RED); } @Override public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) { super.onDraw(c, parent, state); drawLetterToItemLeft(c, parent); } /** * 绘制方法 * @param c 画布 * @param parent RecyclerView */ private void drawLetterToItemLeft(Canvas c, RecyclerView parent) { RecyclerView.LayoutManager layoutManager = parent.getLayoutManager(); if (!(layoutManager instanceof LinearLayoutManager)){ return; } int childCount = parent.getChildCount(); for (int i = 0; i < childCount; i++) { int position = ((LinearLayoutManager) layoutManager).findFirstVisibleItemPosition() + i; View child = parent.getChildAt(i); RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams(); float left = 0; float top = child.getTop() - params.topMargin; float right = child.getLeft() - params.leftMargin; float bottom = child.getBottom() + params.bottomMargin; float width = right - left; float height = bottom - (bottom - top) / 2; //当前名字拼音的第一个字母 String letter = PinyinUtils.getPinyin(mData.get(position)).charAt(0) + ""; if (position == 0) { drawLetter(letter, width, height, c, parent); } else { String preLetter = PinyinUtils.getPinyin(mData.get(position - 1)).charAt(0) + ""; if (!letter.equalsIgnoreCase(preLetter)) { drawLetter(letter, width, height, c, parent); } } } } private void drawLetter(String letter, float width, float height, Canvas c, RecyclerView parent) { float fontLength = getFontLength(paint, letter); float fontHeight = getFontHeight(paint); float tx = (width - fontLength) / 2; float ty = height - fontHeight / 2 + getFontLeading(paint); c.drawText(letter, tx, ty, paint); } @Override public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { super.getItemOffsets(outRect, view, parent, state); outRect.set(dip2px(40), 0, 0, 0); } private int dip2px(int dip) { float density = mContext.getResources().getDisplayMetrics().density; int px = (int) (dip * density + 0.5f); return px; } public int sp2px(int sp) { return (int) (TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, sp, mContext.getResources().getDisplayMetrics()) + 0.5f); } /** * 返回指定笔和指定字符串的长度 */ private float getFontLength(Paint paint, String str) { return paint.measureText(str); } /** * 返回指定笔的文字高度 */ private float getFontHeight(Paint paint) { Paint.FontMetrics fm = paint.getFontMetrics(); return fm.descent - fm.ascent; } /** * 返回指定笔离文字顶部的基准距离 */ private float getFontLeading(Paint paint) { Paint.FontMetrics fm = paint.getFontMetrics(); return fm.leading - fm.ascent; } }

5.3.4、名字数组数据类Cheeses.java

/**
 * Created by ${chenyuexueer}
 * 说明:姓名数据
 */

public class Cheeses {

    public static final String[] NAMES = new String[] { "宋江", "卢俊义", "吴用",
            "公孙胜", "关胜", "林冲", "秦明", "呼延灼", "花荣", "柴进", "李应", "朱仝", "鲁智深",
            "武松", "董平", "张清", "杨志", "徐宁", "索超", "戴宗", "刘唐", "李逵", "史进", "穆弘",
            "雷横", "李俊", "阮小二", "张横", "阮小五", " 张顺", "阮小七", "杨雄", "石秀", "解珍",
            " 解宝", "燕青", "朱武", "黄信", "孙立", "宣赞", "郝思文", "韩滔", "彭玘", "单廷珪",
            "魏定国", "萧让", "裴宣", "欧鹏", "邓飞", " 燕顺", "杨林", "凌振", "蒋敬", "吕方",
            "郭 盛", "安道全", "皇甫端", "王英", "扈三娘", "鲍旭", "樊瑞", "孔明", "孔亮", "项充",
            "李衮", "金大坚", "马麟", "童威", "童猛", "孟康", "侯健", "陈达", "杨春", "郑天寿",
            "陶宗旺", "宋清", "乐和", "龚旺", "丁得孙", "穆春", "曹正", "宋万", "杜迁", "薛永", "施恩",
            "周通", "李忠", "杜兴", "汤隆", "邹渊", "邹润", "朱富", "朱贵", "蔡福", "蔡庆", "李立",
            "李云", "焦挺", "石勇", "孙新", "顾大嫂", "张青", "孙二娘", " 王定六", "郁保四", "白胜",
            "时迁", "段景柱" };

}
5.3.5、activity_main.xml

具体代码----同上(5.1.2、activity_main.xml)

5.3.6、 MyAdapter.java

具体代码----同上(5.1.4、MyAdapter.java)

5.4、悬浮头布局(使用ItemDecoration)

懒得写,将就着看这个吧,这个结合几个效果一起使用《Android二级联动》

MaterialDesign笔记(二)--控/组件简单使用
参考自

你可能感兴趣的:(笔记:MaterialDesign(一)--控/组件简单使用)