Android&java的成长之路之四(自定义字母索引)

    由于过年事情比较繁多,所以空了好久才动手写这片文章,仅仅对自己看的而已。。

    这篇文章主要讲解下自定义的字母索引,在每个App中一般都会用到的,简单的例子就给大家分享下。首先请看下目录是怎么样的:


    

首先呢,MainActivity就是用来显示那个导航的页面 Person是用来模拟一个数据类  最主要的还是SideView了  这个是用来自定义一个索引的导航 

然后,看看源码是怎么实现的吧  从最主要的来说 SideView:


package com.example.administrator.zimudaohang;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

/**
 * Created by Administrator on 2016/2/3 0003.
 */
public class SideView extends View {

    private String[] ZiMu = {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "#"};
    private Paint paint = new Paint();
    private Context context;
    private Canvas canvas;
    private Boolean ShowBG = false;//显示中间小字母?

    public SideView(Context context) {
        super(context);
        this.context = context;
    }

    public SideView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        //获取该空间的宽和高
        float height = this.getHeight();
        float width = this.getWidth();
        //设置画笔的属性
        paint.setColor(Color.RED);
        paint.setTextSize(20);
        paint.setTypeface(Typeface.DEFAULT);
        //设置每个字母所在的高度
        int each_height = (int) (height / ZiMu.length);

        for (int i = 0; i < ZiMu.length; i++) {
            float x = (width - paint.measureText(ZiMu[i])) / 2;
            float y = (1 + i) * each_height;
            canvas.drawText(ZiMu[i], x, y, paint);
        }
    }

    private int choose;//用来存储选中字母的索引
    private OnTouchLetterChangeListenner listenner;

    /**
     * 回调方法,注册监听器
     *
     * @param listenner
     */
    public void setOnTouchLetterChangeListenner(
            OnTouchLetterChangeListenner listenner) {
        this.listenner = listenner;
    }

    /**
     * SlideBar 的监听器接口
     *
     * @author Folyd
     */
    public interface OnTouchLetterChangeListenner {

        void onTouchLetterChange(Boolean ShowBG, String s);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        float y = event.getY();
        final int c = (int) (y / getHeight() * ZiMu.length);//获取点击Y轴坐标总高度的比例*数组的长度就是等于数组中点击的字母索引
        // 保存上次点击的字母的索引到oldChoose
        final int oldChoose = choose;
        switch (event.getAction()) {
            case MotionEvent.ACTION_UP:
                ShowBG = false;
                choose = -1;
                if (listenner != null) {
                    listenner.onTouchLetterChange(ShowBG, ZiMu[c]);
                }
                setBackgroundResource(android.R.color.transparent);
                invalidate();
                break;
            default:
                ShowBG = true;
                setBackgroundResource(android.R.color.darker_gray);
                if (c >= 0 && c < ZiMu.length) {
                     if (listenner != null) {
                    if (oldChoose != c && listenner != null && c >= 0
                            && c < ZiMu.length) {
                        choose = c;
                        listenner.onTouchLetterChange(ShowBG, ZiMu[c]);
                        invalidate();
                    }
                    choose = c;
                     }
                }
                break;
        }
        return true;
    }

}

其实思路是挺简单的 :

首先定义一个SideView类继承View 然后用Android中的绘图技术绘制出该控件的外观,再然后声明他的事件 例如OnTouchEvent事件,该事件要定义监听器 接口之类的 (具体实现方法才找源代码)。


接下来说下主窗口的实现方法:

package com.example.administrator.zimudaohang;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {
    private SideView sideView;
    private TextView textView;
    private ListView listView;
    private List<Person> list;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        sideView= (SideView) findViewById(R.id.sideview);
        textView= (TextView) findViewById(R.id.float_letter);
        listView= (ListView) findViewById(R.id.listView);
        sideView.setOnTouchLetterChangeListenner(new SideView.OnTouchLetterChangeListenner() {
            @Override
            public void onTouchLetterChange(Boolean ShowBG, String s) {
                textView.setText(s);
                if (ShowBG) {
                    textView.setVisibility(View.VISIBLE);
                   // Toast.makeText(MainActivity.this,findIndex(s)+"",Toast.LENGTH_SHORT).show();
                    listView.setSelection(findIndex(s));
                } else {
                    textView.setVisibility(View.GONE);
                }
            }
        });
        getData();
        MyAdapter myAdapter=new MyAdapter();
        listView.setAdapter(myAdapter);
    }
    //获取数据 这个可以根据自己的个人情况来取舍
    private List getData(){

       list=new ArrayList<Person>();
        Person person4=new Person();
        person4.setName("阿门");
        person4.setSort("A");
        person4.setID(0);
        list.add(person4);
        Person person1=new Person();
        person1.setName("明明");
        person1.setSort("M");

        person4.setID(1);
        list.add(person1);
        Person person2=new Person();
        person2.setName("明明2");
        person2.setSort("M");

        person2.setID(2);
        list.add(person2);
        Person person3=new Person();
        person3.setName("明3");
        person3.setSort("M");

        person3.setID(3);
        list.add(person3);
        Person person5=new Person();
        person5.setName("保罗");
        person5.setSort("B");

        person5.setID(5);
        list.add(person5);
        for(int i=6;i<11;i++){
            Person person6=new Person();
            person6.setName("成功"+i);
            person6.setSort("C");
            person6.setID(i);
            list.add(person6);
        }
        Person person7=new Person();
        person7.setName("成功6");
        person7.setSort("C");
        person7.setID(11);
        list.add(person7);
        for(int i=12;i<17;i++){
            Person person6=new Person();
            person6.setName("打的"+i);
            person6.setSort("D");
            person6.setID(i);
            list.add(person6);
        }
        for(int i=18;i<25;i++){
            Person person6=new Person();
            person6.setName("俄方"+i);
            person6.setSort("E");
            person6.setID(i);
            list.add(person6);
        }
        return list;
    }
    private StringBuffer buffer = new StringBuffer();//用来第一次保存首字母的索引
    private List<String> firdList = new ArrayList<String>();//用来保存所有值得城市名称
    //适配器
    private class MyAdapter extends BaseAdapter{

      @Override
      public int getCount() {
          return list.size();
      }

      @Override
      public Object getItem(int position) {
          return list.get(position);
      }

      @Override
      public long getItemId(int position) {
          return position;
      }
      @Override
      public View getView(int position, View convertView, ViewGroup parent) {
          LayoutInflater inflater=getLayoutInflater();
          if(convertView==null){
              convertView=inflater.inflate(R.layout.item,null);
          }
          Person person=list.get(position);
          String sort=person.getSort();
          String name=person.getName();
          int ID=person.getID();
          TextView textView2= (TextView) convertView.findViewById(R.id.item_sort);
          if(buffer.indexOf(sort)==-1){ //索引不存在的话
              buffer.append(sort);//将该字母添加进去
              firdList.add(ID+"");
          }
          if(firdList.contains(ID+"")){
              textView2.setText(sort);
              textView2.setVisibility(View.VISIBLE);
          }else{
              textView2.setVisibility(View.GONE);
          }
          TextView textView= (TextView) convertView.findViewById(R.id.item_name);
          textView.setText(name);
          return convertView;
      }
  }
    //根据索引找到对应的索引位置
    private int findIndex(String s){
        for(int i=0;i<list.size();i++){
            if(s.equals(list.get(i).getSort())){
                return i;
            }
        }
        return -1;
    }

}

其中这个主窗口都挺简单的,主要是吧ListView中的字母和标题之间的关系处理好 什么时候该显示,什么时候不该显示字母索引这个处理好其余的就好办了。

在具体的代码都有介绍  所以就不废话了。

然后主界面和listitem的布局让大家看看:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
    tools:context="com.example.administrator.zimudaohang.MainActivity">

<FrameLayout
    android:layout_weight="1"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <ListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:cacheColorHint="#00000000"
        android:fadingEdge="none"
        android:scrollbars="none" >
    </ListView>
    <TextView
        android:id="@+id/float_letter"
        android:layout_width="80dp"
        android:layout_height="80dp"
        android:layout_gravity="center"
        android:background="#F88701"
        android:gravity="center"
        android:textSize="40sp"
        android:visibility="gone" />

    <com.example.administrator.zimudaohang.SideView
        android:id="@+id/sideview"
        android:layout_width="30dp"
        android:layout_height="match_parent"
        android:layout_centerVertical="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true"
        android:layout_gravity="right|top" />
</FrameLayout>

</RelativeLayout>

listitem布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
        android:id="@+id/item_sort"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:background="#CCCCCC"
        android:padding="8dp"
        android:text="C"
        android:textColor="#000000"
        android:textSize="18dp" />

    <TextView
        android:id="@+id/item_name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="10dp"
        android:text="城市名称"
        android:textColor="#000000"
        android:textSize="15dp" />
</LinearLayout>

最后是一个最简单的数据类的源码

package com.example.administrator.zimudaohang;

/**
 * Created by Administrator on 2016/2/20 0020.
 */
public class Person {
    private String name;
    private String sort;
    private int ID;
    public String getName(){
        return name;
    }
    public void setName(String name){
        this.name=name;
    }
    public String getSort(){
        return sort;
    }
    public void setSort(String sort){
        this.sort=sort;
    }
    public int getID(){
        return ID;
    }
    public void setID(int ID){
        this.ID=ID;
    }
}

到此为止 自定义的字母索引导航就告一段落了。下面是效果图:



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值