仿华为手机联系人悬浮条效果

2020-03-05  本文已影响0人  编程的猫

先上效果:


aa.gif

文字描述我就不写了,直接上代码:
1.中文转拼音工具类,要用到pinyin4android.jar和pinyin4j-2.5.0.jar

public class PingYinUtil implements Comparator<Object> {

    //    @Override
//    public int compare(Object o1, Object o2) {
//        String[] str1=(String[])o1;
//        String[] str2=(String[])o2;
//        String pingYin1 = getPingYin(str1[1]);
//        String pingYin2 = getPingYin(str2[1]);
//        return pingYin1.compareTo(pingYin2);
//    }
    @Override
    public int compare(Object o1, Object o2) {
        String str1 = (String) o1;
        String str2 = (String) o2;
        String pingYin1 = getPingYin(str1.substring(0, 1));
        String pingYin2 = getPingYin(str2.substring(0, 1));
        return pingYin1.compareTo(pingYin2);
    }

    /**
     * 将字符串中的中文转化为拼音,其他字符不变
     */
    public static String getPingYin(String inputString) {
        HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();
        format.setCaseType(HanyuPinyinCaseType.LOWERCASE);
        format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
        format.setVCharType(HanyuPinyinVCharType.WITH_V);

        Pattern p = Pattern.compile("^[\u4E00-\u9FA5A-Za-z_]+$");
        Matcher matcher = p.matcher(inputString.substring(0, 1));
        if (matcher.find()) {
            char[] input = inputString.trim().toCharArray();
            String output = "";
            try {
                for (int i = 0; i < input.length; i++) {
                    if (Character.toString(input[i]).matches("[\\u4E00-\\u9FA5]+")) {
                        String[] temp = PinyinHelper.toHanyuPinyinStringArray(input[i], format);
                        output += temp[0];
                    } else
                        output += Character.toString(input[i]);
                }
            } catch (BadHanyuPinyinOutputFormatCombination e) {
                e.printStackTrace();
            }
            return output;
        } else {
            return "";
        }
    }

    public static String converterToFirstSpell(String chines) {
        String pinyinName = "";
        char[] nameChar = chines.toCharArray();
        HanyuPinyinOutputFormat defaultFormat = new HanyuPinyinOutputFormat();
        defaultFormat.setCaseType(HanyuPinyinCaseType.UPPERCASE);
        defaultFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
        for (int i = 0; i < nameChar.length; i++) {
            if (nameChar[i] > 128) {
                try {
                    pinyinName += PinyinHelper.toHanyuPinyinStringArray(nameChar[i], defaultFormat)[0].charAt(0);
                } catch (BadHanyuPinyinOutputFormatCombination e) {
                    e.printStackTrace();
                }
            } else {
                pinyinName += nameChar[i];
            }
        }
        return pinyinName;
    }
}

或者使用系统自带的中文根据拼音排序,以下是工具类

/**
 * android官方提供的排序方法
 */
public class CheaseChatCom implements Comparator {
    @Override
    public int compare(Object o1, Object o2) {
        //中文排序
        Collator collator = Collator.getInstance(Locale.CHINA);
        if (collator.compare(o1, o2) < 0)
            return -1;
        else if (collator.compare(o1, o2) > 0)
            return 1;
        else
            return 0;
    }
}

数据分类

/**
 * 每一条item的数据
 */
public class ItemEntity {
    String name;
    String title;
    Boolean showTitle;

    public ItemEntity(String name, String title,Boolean showTitle) {
        this.name = name;
        this.title = title;
        this.showTitle=showTitle;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public Boolean getShowTitle() {
        return showTitle;
    }

    public void setShowTitle(Boolean showTitle) {
        this.showTitle = showTitle;
    }

    @Override
    public String toString() {
        return "ItemEntity{" +
                "name='" + name + '\'' +
                ", title='" + title + '\'' +
                ", showTitle=" + showTitle +
                '}';
    }
}

用到的adapter

public class Test3Adapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    public static final Integer TITLE_ITEM = 0x10;
    public static final Integer NORMAL_ITEM = 0x11;
    public static final Integer ZORE_ITEM = 0x12;

    List<ItemEntity> data;

    public Test3Adapter(List<ItemEntity> data) {
        this.data = data;
    }

    public List<ItemEntity> getData() {
        return data;
    }

    @Override
    public int getItemViewType(int position) {
        if (position == 0) {
            return ZORE_ITEM;
        } else {
            ItemEntity itemEntity = data.get(position-1);
            Boolean showTitle = itemEntity.getShowTitle();
            if (showTitle) {
                return TITLE_ITEM;
            } else {
                return NORMAL_ITEM;
            }
        }
    }

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        if (viewType==ZORE_ITEM){
            return new Holder2(LayoutInflater.from(parent.getContext()).inflate(
                    R.layout.rv_zore_item, parent, false
            ));
        }else {
            return new Holder(LayoutInflater.from(parent.getContext()).inflate(
                    R.layout.rv_item, parent, false
            ));
        }
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
        if (holder instanceof Holder){
            ItemEntity itemEntity = data.get(position-1);
            Boolean showTitle = itemEntity.getShowTitle();
            if (showTitle) {
                if (position == 1) {
                    ((Holder)holder).title.setVisibility(View.GONE);
                } else {
                    ((Holder)holder).title.setText(itemEntity.getTitle());
                    ((Holder)holder).title.setVisibility(View.VISIBLE);
                }
            } else {
                ((Holder)holder).title.setVisibility(View.GONE);
            }
            ((Holder)holder).content.setText(itemEntity.getName());
        }
    }

    @Override
    public int getItemCount() {
        return data.size()+1;
    }

    static class Holder extends RecyclerView.ViewHolder {

        private final TextView title;
        private final TextView content;

        Holder(@NonNull View itemView) {
            super(itemView);
            title = itemView.findViewById(R.id.title);
            content = itemView.findViewById(R.id.content);

        }
    }

    static class Holder2 extends RecyclerView.ViewHolder {

        Holder2(@NonNull View itemView) {
            super(itemView);

        }
    }
}

adapter用到的布局

<?xml version="1.0" encoding="utf-8"?>
<View xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="40dp"
    android:orientation="vertical" />
<?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:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@android:color/white"
    android:orientation="vertical">

    <TextView
        android:id="@+id/title"
        android:layout_width="match_parent"
        android:layout_height="36dp"
        android:gravity="center_vertical"
        android:paddingStart="12dp"
        android:paddingLeft="12dp"
        android:textColor="@android:color/darker_gray"
        android:textSize="15sp"
        tools:ignore="RtlSymmetry"
        tools:text="A" />

    <TextView
        android:id="@+id/content"
        android:layout_width="match_parent"
        android:layout_height="42dp"
        android:gravity="center_vertical"
        android:paddingStart="12dp"
        android:paddingLeft="12dp"
        android:textColor="@android:color/black"
        android:textSize="16sp"
        tools:ignore="RtlSymmetry"
        tools:text="阿塞拜疆" />
</LinearLayout>

在activity中使用

public class Main3Activity extends AppCompatActivity {
    final String TAG = getClass().getSimpleName();

    List<String> labelList = new ArrayList<>();
    
    private StringBuilder sb;
    private RecyclerView rv;
    private AppCompatTextView label;
    private LinearLayoutManager manager;
    private Test3Adapter test3Adapter;

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

        rv = findViewById(R.id.rv);
        label = findViewById(R.id.label);

        manager = new LinearLayoutManager(
                this, RecyclerView.VERTICAL, false);
        rv.setLayoutManager(manager);

        labelList.add("阿凡达");
        labelList.add("浙江");
        labelList.add("舒服可");
        labelList.add("湖北");
        labelList.add("河南");
        labelList.add("江苏");
        labelList.add("广东");
        labelList.add("四川");
        labelList.add("新疆");
        labelList.add("西藏");
        labelList.add("江门");
        labelList.add("阿叔克");
        labelList.add("林芝");
        labelList.add("陕西");
        labelList.add("北京");
        labelList.add("江西");
        labelList.add("阿塞拜疆");
        labelList.add("南京");
        labelList.add("阿福级");
        labelList.add("山西");
        labelList.add("天津");
        labelList.add("上海");
        labelList.add("阿骨打");
        labelList.add("杭州");
        labelList.add("武汉");
        labelList.add("武威");
        labelList.add("山东");

        CheaseChatCom cheaseChatCom = new CheaseChatCom();
        Collections.sort(labelList, cheaseChatCom);
        if (sb == null)
            sb = new StringBuilder();
        List<ItemEntity> itemEntities = new ArrayList<>();
        for (String s : labelList) {
            String aCase = PingYinUtil.getPingYin(s).substring(0, 1).toUpperCase();
//            Log.i(TAG, "=======  " + aCase);
            if (!sb.toString().contains(aCase)) {
                ItemEntity itemEntity = new ItemEntity(s, aCase, true);
                itemEntities.add(itemEntity);
                sb.append(aCase);
            } else {
                ItemEntity itemEntity = new ItemEntity(s, aCase, false);
                itemEntities.add(itemEntity);
            }
        }
        test3Adapter = new Test3Adapter(itemEntities);
        rv.setAdapter(test3Adapter);
        label.setText(itemEntities.get(0).getTitle());
        rvScrollListener();
//        String s = append.toString();
//        Log.i(TAG, s);

    }

    private int labelHeight;
    private int mCurrentPosition;

    private void rvScrollListener() {
        rv.addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
                super.onScrollStateChanged(recyclerView, newState);
                labelHeight = label.getHeight();
            }

            @Override
            public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                if (mCurrentPosition != 0 && test3Adapter.getItemViewType(mCurrentPosition + 1)
                        == Test3Adapter.TITLE_ITEM) {
                    View nextView = manager.findViewByPosition(mCurrentPosition + 1);
                    if (nextView != null) {
                        float y = nextView.getTop();
                        if (y <= labelHeight) {
                            float v = labelHeight - y;
                            label.setY(-v);
                        } else {
                            label.setY(0);
                        }
                    }
                }
                //manager.findFirstVisibleItemPosition() 获取当前窗口可以看见的第一个Item的位置
                if (mCurrentPosition != manager.findFirstVisibleItemPosition()) {
                    mCurrentPosition = manager.findFirstVisibleItemPosition();
                    Log.i(TAG, "======   mCurrentPosition:" + mCurrentPosition);
                    if (mCurrentPosition == 0) {
                        updateSuspensionBar(mCurrentPosition);
                    } else {
                        updateSuspensionBar(mCurrentPosition - 1);
                    }
                    label.setY(0);
                }
            }
        });
    }

    private void updateSuspensionBar(int position) {
        List<ItemEntity> data = test3Adapter.getData();
        if (data != null) {
            ItemEntity itemEntity = data.get(position);
            label.setText(itemEntity.getTitle());
        }
    }
}

activity的布局

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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"
    android:orientation="vertical"
    android:background="@android:color/white"
    tools:context=".activitys.Main3Activity">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <androidx.appcompat.widget.AppCompatTextView
        android:id="@+id/label"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:paddingStart="12dp"
        android:background="@android:color/white"
        android:gravity="center_vertical"
        android:textColor="@android:color/darker_gray"
        android:textSize="16sp"
        android:textStyle="bold"
        tools:text="标签"
        android:paddingLeft="12dp"
        tools:ignore="RtlSymmetry" />

</FrameLayout>

参考博文:https://www.jianshu.com/p/0a7ec9580cb9
另外有一篇博文是通过RecyclerView的分隔线实现的,我没有去实现,各位有兴趣可以试下:https://www.jianshu.com/p/f4e3abfab18c

上一篇下一篇

猜你喜欢

热点阅读