Android頭部懸浮ListView第二種實現方式
阿新 • • 發佈:2019-02-14
上篇部落格,根據幾位大神的部落格總結出了一篇ListView懸浮,快速索引。效果非常不錯,而且易於擴充套件,可在實際專案中並不是很通用,因為總需要實現SectionIndexer介面,比較複雜而且不是所有的分且頭部都是由A-Z 這種分組,也可能是以任意條件的分組,比如時間。這種情況下上一篇的方法就不能用了。本篇則是基於上一篇的程式碼修改,使的ListView不再去實現SectionIndexer.修改OnScrollListener中的監聽,使得可懸浮ListView能夠基本通用。
效果與上篇完全一樣。
程式碼如下:
1.adapter程式碼
/**
* @description 通用Adapter
* @author rzq
* @date 2015
*/
public class SortAdapter extends BaseAdapter
{
private List<SortModel> list = null;
private Context mContext;
private SortModel country;
private ViewHolder holder1, holder2;
public SortAdapter(Context mContext, List<SortModel> list)
{
this .mContext = mContext;
this.list = list;
}
@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)
{
country = (SortModel) list.get(position);
int type = getItemViewType(position);
if (convertView == null)
{
switch (type)
{
case 0:
holder1 = new ViewHolder();
convertView = LayoutInflater.from(mContext).inflate(R.layout.item_group, parent, false);
holder1.tvTitle = (TextView) convertView.findViewById(R.id.catalog);
convertView.setTag(holder1);
break;
case 1:
holder2 = new ViewHolder();
convertView = LayoutInflater.from(mContext).inflate(R.layout.item, parent, false);
holder2.tvTitle = (TextView) convertView.findViewById(R.id.title);
convertView.setTag(holder2);
break;
}
}
else
{
switch (type)
{
case 0:
holder1 = (ViewHolder) convertView.getTag();
break;
case 1:
holder2 = (ViewHolder) convertView.getTag();
break;
}
}
switch (type)
{
case 0:
holder1.tvTitle.setText(country.getSortLetters());
break;
case 1:
holder2.tvTitle.setText(country.getName());
break;
}
return convertView;
}
@Override
public int getItemViewType(int position)
{
country = (SortModel) getItem(position);
if (country.isGroup())
{
return 0;
}
else
{
return 1;
}
}
@Override
public int getViewTypeCount()
{
return 2;
}
final static class ViewHolder
{
TextView tvTitle;
}
}
上述程式碼是一個最普通的多佈局Adapter寫法,無需實現SectionIndex.
2.Activity程式碼:
public class MainActivity extends Activity
{
private ListView sortListView;
private SortAdapter adapter;
private CharacterParser characterParser;
private List<SortModel> SourceDateList;
private PinyinComparator pinyinComparator;
private LinearLayout titleLayout;
private TextView title;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initViews();
}
private void initViews()
{
titleLayout = (LinearLayout) findViewById(R.id.title_layout);
title = (TextView) findViewById(R.id.title);
characterParser = CharacterParser.getInstance();
pinyinComparator = new PinyinComparator();
sortListView = (ListView) findViewById(R.id.country_lvcountry);
SourceDateList = filledData(getResources().getStringArray(R.array.date));
Collections.sort(SourceDateList, pinyinComparator);
adapter = new SortAdapter(this, SourceDateList);
sortListView.setAdapter(adapter);
sortListView.setOnScrollListener(new OnScrollListener()
{
@Override
public void onScrollStateChanged(AbsListView view, int scrollState)
{
}
/**
* AbsListView滑動時執行
*/
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount)
{
/**
* 取出列表相臨兩項
*/
SortModel modelFirst = (SortModel) adapter.getItem(firstVisibleItem);
SortModel modelSecond = (SortModel) adapter.getItem(firstVisibleItem + 1);
if (firstVisibleItem != lastFirstVisibleItem)
{
MarginLayoutParams params = (MarginLayoutParams) titleLayout.getLayoutParams();
params.topMargin = 0;
titleLayout.setLayoutParams(params);
if (modelFirst.getSortLetters() != null)
{
title.setText(modelFirst.getSortLetters());
}
}
/**
* 相臨兩組Data狀態不同,且第一組資料的狀態為普 通資料,第二組資料為Group,則符合懸浮的條件,開始進行判斷部懸浮計算
*/
if (modelFirst.isGroup() == false && modelSecond.isGroup() == true)
{
View childView = view.getChildAt(1);
if (childView != null)
{
int titleHeight = titleLayout.getHeight();
int top = childView.getTop();
MarginLayoutParams params = (MarginLayoutParams) titleLayout.getLayoutParams();
if (top <= titleHeight)
{
float pushedDistance = -(titleHeight - top);
params.topMargin = (int) pushedDistance;
titleLayout.setLayoutParams(params);
}
}
}
lastFirstVisibleItem = firstVisibleItem;
}
});
}
private int lastFirstVisibleItem = -1;
private List<SortModel> filledData(String[] date)
{
List<SortModel> mSortList = new ArrayList<SortModel>();
for (int i = 0; i < date.length; i++)
{
SortModel sortModel = new SortModel();
sortModel.setName(date[i]);
/**
* 添加了Group資料,[A-Z]
*/
if (date[i].matches("[A-Z]"))
{
sortModel.setSortLetters(date[i]);
sortModel.setGroup(true);
}
else
{
String pinyin = characterParser.getSelling(date[i]);
String sortString = pinyin.substring(0, 1).toUpperCase();
if (sortString.matches("[A-Z]"))
{
sortModel.setSortLetters(sortString.toUpperCase());
}
else
{
sortModel.setSortLetters("#");
}
sortModel.setGroup(false);
}
mSortList.add(sortModel);
}
return mSortList;
}
}
通過上述程式碼可以看出,通過這訲方式實現的效果更加的通用,也是在研究了多位大神的部落格後,自己有了改進的想法,編碼實現了自己的想法。使用這訲不重寫ListView的方式,我們還可以結合PullToRefresh做上下拉重新整理,而如果你重定義ListView則很難再與其它開源庫相結合。這是使用這一方式最大的優勢。