您的位置:首页 > 其它

ListView 右侧导航

2016-01-08 14:16 162 查看




src 中的 MainActivity:

public class MainActivity extends Activity implements OnItemClickListener {
    /**
     * 显示城市列表的ListView控件
     */
    private ListView lvCityList;
    /**
     * 显示城市列表的ListView的数据源
     */
    private List<City> cityList;
    /**
     * 显示城市列表的ListView的Adapter
     */
    private CityAdapter cityAdapter;
    /**
     * 显示右侧字母导航的ListView控件
     */
    private ListView lvSideBar;
    /**
     * 显示右侧字母导航的ListView的数据源
     */
    private List<String> sortKeys;
    /**
     * 显示右侧字母导航的ListView的Adapter
     */
    private SideBarAdapter sideBarAdapter;

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

        // 初始化ListView
        lvCityList = (ListView) findViewById(R.id.lv_city_list);
        // 获取数据源
        cityList = getCityListData();
        // 对城市列表排序
        sortCityListByPinyin(cityList);
        // 创建adapter
        cityAdapter = new CityAdapter(this, cityList);
        // 为ListView配置adapter
        lvCityList.setAdapter(cityAdapter);
        
        // 初始化右侧字母导航的ListView
        lvSideBar = (ListView) findViewById(R.id.lv_side_bar);
        // 获取数据源
        sortKeys = getSideBarData();
        // 创建adapter
        sideBarAdapter = new SideBarAdapter(this, sortKeys);
        // 为ListView配置adapter
        lvSideBar.setAdapter(sideBarAdapter);
        // 为ListView配置Item点击监听器
        lvSideBar.setOnItemClickListener(this);
    }

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position,
            long id) {
        // 根据poisiton获取被点击的字母
        String str = sortKeys.get(position);
        // 把点击的字母转换成char类型
        char ch = str.charAt(0);
        // 获取该字母在城市列表中出现的位置
        int moveToPosition = cityAdapter.getPositionForSection(ch);
        // 城市列表的ListView快速移动到指定位置
        if(moveToPosition != -1) {
            lvCityList.setSelection(moveToPosition);
        }
    }

    /**
     * 根据拼音将城市列表排序
     */
    private void sortCityListByPinyin(List<City> data) {
        Collections.sort(data, new Comparator<City>() {
            @Override
            public int compare(City lhs, City rhs) {
                return lhs.getPinyin().compareTo(rhs.getPinyin());
            }
        });
    }

    /**
     * 获取城市列表的数据源
     *
     * @return 城市列表的数据源
     */
    private List<City> getCityListData() {
        List<City> data = new ArrayList<City>();

        data.add(new City("北京", "beijing"));
        data.add(new City("上海", "shanghai"));
        data.add(new City("广州", "guangzhou"));
        data.add(new City("深圳", "shenzhen"));
        data.add(new City("成都", "chengdu"));
        data.add(new City("重庆", "chongqing"));
        data.add(new City("大连", "dalian"));
        data.add(new City("厦门", "xiamen"));
        data.add(new City("丽江", "lijiang"));
        data.add(new City("三亚", "sanya"));
        data.add(new City("青岛", "qingdao"));
        data.add(new City("铁岭", "tieling"));
        data.add(new City("攀枝花", "panzhihua"));
        data.add(new City("杭州", "hangzhou"));
        data.add(new City("苏州", "suzhou"));
        data.add(new City("南京", "nanjing"));
        data.add(new City("武汉", "wuhan"));
        data.add(new City("哈尔滨", "haerbin"));

        return data;
    }

    /**
     * 获取右侧字母导航的数据源
     *
     * @return 右侧字母导航的数据源
     */
    private List<String> getSideBarData() {
        List<String> data = new ArrayList<String>();

        // 根据CityAdapter中的getSections()获取所有应该显示的首字母
        String[] arr = (String[]) cityAdapter.getSections();
        // 对数组进行排序
        Arrays.sort(arr);
        // 将数组转换成List
        data = Arrays.asList(arr);

        return data;
    }

}

src 中的 SideBarAdapter:public class SideBarAdapter extends BaseAdapter {
private Context context;
private List<String> data;
private LayoutInflater inflater;

public SideBarAdapter(Context context, List<String> data) {
super();
this.context = context;
this.setData(data);

inflater = LayoutInflater.from(this.context);
}

public void setData(List<String> data) {
if (data == null) {
data = new ArrayList<String>();
}
this.data = data;
}

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

@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if(convertView == null) {
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.side_bar_item, null);
holder.tvSortKey = (TextView) convertView.findViewById(R.id.tv_side_bar_item_sort_key);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}

holder.tvSortKey.setText(data.get(position));

return convertView;
}

private class ViewHolder {
TextView tvSortKey;
}

@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return null;
}

@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
}
src 中的 CityAdapter:
public class CityAdapter
extends BaseAdapter
implements SectionIndexer {
/**
* 上下文对象
*/
private Context context;
/**
* 数据源
*/
private List<City> data;
/**
* 将XML布局加载为View对象的工具
*/
private LayoutInflater inflater;

/**
* 构造方法
*
* @param context
*            上下文对象
* @param data
*            数据源
*/
public CityAdapter(Context context, List<City> data) {
super();
this.context = context;
this.setData(data);

inflater = LayoutInflater.from(this.context);
}

/**
* 设置数据源
*
* @param data
*            数据源
*/
public void setData(List<City> data) {
if (data == null) {
data = new ArrayList<City>();
}
this.data = data;
}

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

// private String lastSortKey;

@Override
public View getView(int position, View convertView, ViewGroup parent) {
// 准备ViewHolder
ViewHolder holder;
// 判断convertView参数是否为空
if (convertView == null) {
// 当convertView为空时,需要根据布局进行加载,并创建ViewHolder,完成初始化,将ViewHolder封装到convertView,以至于重用convertView时,可以直接获取ViewHolder
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.city_item, null);
holder.tvCitySortKey = (TextView) convertView
.findViewById(R.id.tv_city_sort_key);
holder.tvCityName = (TextView) convertView
.findViewById(R.id.tv_city_name);
convertView.setTag(holder);
} else {
// 当convertView不为空时,则表示它是被系统自动重用的,则它内部的控件也是重用的
holder = (ViewHolder) convertView.getTag();
}

// 获取当前需要显示的数据
City city = data.get(position);

if(position == getPositionForSection(getSectionForPosition(position))) {
// 当前位置与“根据位置找到的section,然后根据section找到应该出现的位置”相等,则显示section
holder.tvCitySortKey.setVisibility(View.VISIBLE);
} else {
// position与section出现的position不相等,则不显示
holder.tvCitySortKey.setVisibility(View.GONE);
}

//		// 获取当前的sort key
//		String currentSortKey = city.getPinyin().toUpperCase(Locale.CHINA)
//				.substring(0, 1);
// // 对比是否与上一条相同,且必须是position > 0时进行对比(第1条记录不需要对比)
// if(position > 0 && currentSortKey.equals(
// data.get(position - 1)
// .getPinyin().
// toUpperCase(Locale.CHINA)
// .substring(0, 1))) {
// // 相同,隐藏
// holder.tvCitySortKey.setVisibility(View.GONE);
// } else {
// // 不同,显示
// holder.tvCitySortKey.setVisibility(View.VISIBLE);
// }

// 设置控件的显示
holder.tvCitySortKey.setText("" + ((char)getSectionForPosition(position)));
holder.tvCityName.setText(city.getName());

// 返回
return convertView;
}

private class ViewHolder {
TextView tvCitySortKey, tvCityName;
}

@Override
public int getPositionForSection(int section) {
int currentSection;
for (int i = 0; i < data.size(); i++) {
// 找到当次循环到的城市数据的section
currentSection = getSectionForPosition(i);
// 判断当次的section是否与参数section匹配
// 如果匹配,则当前循环的次数就是所需要的position,且跳出循环
if(currentSection == section) {
return i;
}
}
return -1;
}

@Override
public int getSectionForPosition(int position) {
return data.get(position).getPinyin().toUpperCase(Locale.CHINA).charAt(0);
}

// 以下抽象方法可以不具体实现

@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return null;
}

@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}

@Override
public Object[] getSections() {
// 基于Set容器内部数据的唯一性,先使用Set保存所有数据对应的首字母
Set<String> set = new HashSet<String>();
for (int i = 0; i < data.size(
a47d
); i++) {
set.add("" + ((char)getSectionForPosition(i)));
}
Log.d("", "section count -> " + set.size());

// 根据Set的大小创建数组
String[] arr = new String[set.size()];
// 循环整个Set,把每个元素添加到数组
int i = 0;
for (String string : set) {
Log.d("", "set string -> " + string);
arr[i] = string;
Log.d("", "arr[" + i + "]" + arr[i]);
i++;
}

// 返回
return arr;
}
}

src 中的 City:public class City {

private String name;
private String pinyin;

public City() {
super();
}

public City(String name, String pinyin) {
super();
this.name = name;
this.pinyin = pinyin;
}

public String getName() {
return name;
}

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

public String getPinyin() {
return pinyin;
}

public void setPinyin(String pinyin) {
this.pinyin = pinyin;
}

}layout 中的 activity_main.xml:
<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"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >

<ListView
android:id="@+id/lv_city_list"
android:layout_width="match_parent"
android:layout_height="match_parent" />

<ListView
android:id="@+id/lv_side_bar"
android:layout_width="20dp"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:divider="@null" >
</ListView>

</RelativeLayout>
layout 中的 city_item.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >

<TextView
android:id="@+id/tv_city_sort_key"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#cccccc"
android:paddingBottom="2dp"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:paddingTop="2dp"
android:text="C"
android:textSize="12sp" />

<TextView
android:id="@+id/tv_city_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/tv_city_sort_key"
android:paddingBottom="5dp"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:paddingTop="5dp"
android:text="成都"
android:textSize="16sp" />

</RelativeLayout>layout 中的 side_bar_item.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >

<TextView
android:id="@+id/tv_side_bar_item_sort_key"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:textSize="12sp"
android:text="A" />

</RelativeLayout>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: