先前公司有个需求,让我们做一个城市列表页,不是常见的侧边快速索引,也不是粘性头部的滑动模式,而是分组城市可折叠的模式,自己研究了下,实现这个效果:
接下来说下我的实现思路:目前这个列表主要分为两部分——热门城市和所有城市列表,相当于是两个不同类型的布局,我在做的时候使用的是ListView的添加头部的方式,把热门城市作为头部添加到lListView中,接下来再做城市列表实现。这是一种思路,其实分类型应该也可以实现这个功能,我只分析我这里实现的思路,分类型大家可以自己去尝试尝试。
一、设置滑动列表布局
添加ListView控件在你的布局文件中:
<ListView
android:id="@+id/public_allcity_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:cacheColorHint="@android:color/transparent"
android:divider="@null"
android:listSelector="@android:color/transparent" />
将热门城市作为ListView的头部添加到列表中:
/**
* 添加listview的头部——热门城市
*/
private void addListHead() {
LayoutInflater localLayoutInflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
View hotBlank = localLayoutInflater.inflate(R.layout.location_layout, publicAllcityList, false);
gvCityLabel = hotBlank.findViewById(R.id.gv_city_label);
publicAllcityList.addHeaderView(hotBlank);
}
<?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="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="10dp"
android:paddingLeft="15dp"
android:paddingTop="10dp"
android:text="热门城市"
android:textColor="@color/gray_666666"
android:textSize="14sp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white_ffffff"
android:orientation="horizontal"
android:paddingBottom="28dp"
android:paddingTop="28dp">
<GridView
android:id="@+id/gv_city_label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:gravity="center"
android:listSelector="@android:color/transparent"
android:numColumns="5"
android:overScrollMode="never"
android:paddingLeft="20dp"
android:paddingRight="20dp"
android:scrollbars="none"
android:verticalSpacing="20dp"></GridView>
</LinearLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="15dp"
android:paddingBottom="10dp"
android:paddingTop="10dp"
android:text="所有城市"
android:textColor="@color/gray_666666"
android:textSize="14sp" />
</LinearLayout>
二、设置热门城市
上面已经实现将热门城市作为头部添加到列表中,下来我们只要给热门添加数据和适配器,就可以实现头部的效果。
其中:hotData是模拟的热门城市的数据,cityAdapter是热门城市的适配器
/**
* 热门城市适配器
*/
private void setHotAdapter() {
cityAdapter = new GridAdapter(this, hotData);
gvCityLabel.setAdapter(cityAdapter);
ListViewUtils.fixGridViewHeight(gvCityLabel, 5);
gvCityLabel.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
cityAdapter.setPostion(position);
cityAdapter.notifyDataSetChanged();
}
});
}
在适配器中先加载数据到列表头部,然后根据position的切换设置样式的变换效果:
if (position == currentPostion) {//选中的标签样式
city.setBackgroundResource(R.drawable.raduis_stroken_orange_bg);
city.setTextColor(UIUtils.getColorResource(context, R.color.white_ffffff));
} else {//未选中的标签样式
city.setBackgroundResource(R.drawable.raduis_stroken_white_bg);
city.setTextColor(UIUtils.getColorResource(context, R.color.gray_333333));
}
热门城市的效果就可以实现了。
三、设置可折叠城市列表
在这里我使用一些模拟的城市数据,然后对城市进行排序并且根据首字母情况进行排序,具体的方法我就不列举了。然后设置适配器,在适配器进行数据的加载以及折叠的设置,数据加载就是简单适配器的使用,折叠设置是根据点击positon来设置分组城市的显示和隐藏来进行实现的:
if (shrinks.get(position)) {
gvCityLabel.setVisibility(View.VISIBLE);
ivShrinkOrDisplay.setImageResource(R.drawable.destination_shrink);
} else {
gvCityLabel.setVisibility(View.GONE);
ivShrinkOrDisplay.setImageResource(R.drawable.destination_unfold);
}
在折叠的按钮那做一个点击监听,可以随时知道需要折叠还是展开,对适配器数据进行即时更新
llShrinkOrUnfolder.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (shrinks.get(position)) {
isShrink = false;
} else {
isShrink = true;
}
shrinks.set(position, isShrink);
setShrinks(shrinks);
notifyDataSetChanged();
}
});
分组中的城市具体的样式和热门城市适配器中设置的样式是类似的,可以复用热门城市的适配器来进行具体分组城市每个城市的样式。
到这里基本就可以实现以上的功能,当然我们也可以对ListView做一些item点击效果,具体看个人的需求。还是一样,有什么问题希望大家可以积极对我提出来,我会学习改进的哈~
完整的资源文件可参考:可折叠城市列表项目