最近用定外卖App时发现他们的商品展示页用了固定标题的列表,感觉挺不错的,上网查资料发现开源框架PinnedSectionListView能实现类似功能,于是就写了这个demo,希望对想实现类似功能的小伙伴有所启发。
PinnedSectionListView项目地址:https://github.com/beworker/pinned-section-listview
demo下载地址:http://download.csdn.net/download/shenyuanqing/9048531
效果图:
源码:
MainActivity
package com.example.shen.interfacetest.activity;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.ListView;
import com.example.shen.interfacetest.R;
import com.example.shen.interfacetest.adapter.LeftAdapter;
import com.example.shen.interfacetest.adapter.RightAdapter;
import com.example.shen.interfacetest.bean.Left;
import com.hb.views.PinnedSectionListView;
import java.util.ArrayList;
public class MainActivity extends Activity {
private RightAdapter rightAdapter;
private LeftAdapter leftAdapter;
private PinnedSectionListView pslvRight;
private ListView lvLeft;
private ArrayList<Left> alLeft;
private int posi=0;
private int pos=0;
private int first=0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lvLeft=(ListView) findViewById(R.id.lv_left);
pslvRight=(PinnedSectionListView)findViewById(R.id.pslv_right);
alLeft=new ArrayList<>();
leftAdapter=new LeftAdapter(this,alLeft);
lvLeft.setAdapter(leftAdapter);
initData();
/** 点击左边ListView重定位右边psListView中数据**/
lvLeft.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
pslvRight.setSelection(Integer.parseInt(alLeft.get(position).info));
posi = position;
initData();
}
});
/**得到左边ListView第一列的位置(显示左边ListView被选中但被隐藏的Item时用)**/
lvLeft.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
first=firstVisibleItem;
}
});
ArrayList<String> alString=new ArrayList<>();
for (int i=0;i<100;i++){
alString.add("");
}
rightAdapter=new RightAdapter(this,alString);
pslvRight.setAdapter(rightAdapter);
/**滚动右边psListView刷新左边ListView选中状态**/
pslvRight.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
if(firstVisibleItem!=pos) {
posi = firstVisibleItem / 5;
initData();
pos=firstVisibleItem;
}
}
});
}
private void initData(){
alLeft.clear();
int j=0;
for (int i=0;i<100;i++){
if(i%5==0){
Left left=new Left();
left.info=i+"";
if(posi==j){
left.pos=1;
}else {
left.pos = 0;
}
alLeft.add(left);
j++;
}
}
leftAdapter.notifyDataSetChanged();
changePosition();
}
/**显示左边ListView被选中但被隐藏的Item**/
private void changePosition(){
if(posi-first>=14){
lvLeft.setSelection(first+1);
}
if(posi<first){
lvLeft.setSelection(posi);
}
}
}
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<ListView
android:id="@+id/lv_left"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="2">
</ListView>
<com.hb.views.PinnedSectionListView
android:id="@+id/pslv_right"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"/>
</LinearLayout>
LeftAdapter
package com.example.shen.interfacetest.adapter;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.example.shen.interfacetest.R;
import com.example.shen.interfacetest.bean.Left;
import java.util.ArrayList;
/**
* Created by shen on 2015/8/24.
*/
public class LeftAdapter extends BaseAdapter {
private Context context;
private ArrayList<Left> list;
private LayoutInflater inflater;
public LeftAdapter(Context context,ArrayList<Left> list){
this.context=context;
this.list=list;
inflater=LayoutInflater.from(context);
}
@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) {
ViewHolder viewHolder;
if(convertView==null){
convertView=inflater.inflate(R.layout.item_left_list,null);
viewHolder=new ViewHolder();
viewHolder.tvContent=(TextView) convertView.findViewById(R.id.tv_content);
viewHolder.llMain=(LinearLayout) convertView.findViewById(R.id.ll_main);
convertView.setTag(viewHolder);
}else{
viewHolder=(ViewHolder) convertView.getTag();
}
viewHolder.tvContent.setText(list.get(position).info);
if(list.get(position).pos==1){
viewHolder.llMain.setBackgroundResource(R.color.white);
}else{
viewHolder.llMain.setBackgroundResource(R.color.linen);
}
return convertView;
}
static class ViewHolder{
TextView tvContent;
LinearLayout llMain;
}
}
RightAdapter
package com.example.shen.interfacetest.adapter;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.example.shen.interfacetest.R;
import com.hb.views.PinnedSectionListView;
import java.util.ArrayList;
/**
* Created by shen on 2015/8/22.
*/
public class RightAdapter extends BaseAdapter implements PinnedSectionListView.PinnedSectionListAdapter {
private Context context;
private ArrayList<String> list;
private LayoutInflater inflater;
public RightAdapter(Context context, ArrayList<String> list) {
this.context = context;
this.list = list;
inflater = LayoutInflater.from(context);
}
@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) {
ViewHolder viewHolder;
if(convertView==null) {
convertView = inflater.inflate(R.layout.item_test, null);
viewHolder=new ViewHolder();
viewHolder.tvNum = (TextView) convertView.findViewById(R.id.tv_num);
viewHolder.llMain=(LinearLayout) convertView.findViewById(R.id.ll_main);
convertView.setTag(viewHolder);
}else{
viewHolder=(ViewHolder) convertView.getTag();
}
viewHolder.tvNum.setText(position+"");
if (position%5 == 0) {
viewHolder.llMain.setBackgroundResource(R.color.linen);
} else {
viewHolder.llMain.setBackgroundResource(R.color.white);
}
return convertView;
}
static class ViewHolder{
TextView tvNum;
LinearLayout llMain;
}
/**
* 根据getItemViewType方法返回结果最终确定是否是标题行
* @param viewType
* @return true:标题行 false:普通行
*/
@Override
public boolean isItemViewTypePinned(int viewType) {
if (viewType == 1) {
return true;
} else
return false;
}
/**
* 确定psListView中哪一行是标题行
* @param position
* @return 1:标题行 0:普通行
*/
@Override
public int getItemViewType(int position) {
// TODO Auto-generated method stub
if (position%5 == 0) {
return 1;
} else {
return 0;
}
}
@Override
public int getViewTypeCount() {
return 2;
}
}
Left
public class Left {
public String info;
public int pos;
}