gpt4 book ai didi

android - 如何向我的 ListView 添加粘性 header ?

转载 作者:太空宇宙 更新时间:2023-11-03 11:40:06 26 4
gpt4 key购买 nike

我有一个 listView,所以我想添加一个粘性 header ,以便它粘在 listView 的顶部,当 listView 中开始一个不同的类别时,一个不同的 header 将取代它,就像联系人一样,“a"作为 Sticky header 位于顶部,直到 "b"出现。有没有图书馆可以做到这一点?我正在使用自定义列表适配器来显示我的列表...

这是我的自定义适配器类

public class NewsRowAdapter extends ArrayAdapter<Item>  {

private Activity activity;
private List<Item> items;
private Item objBean;
private int row;

private DisplayImageOptions options;
ImageLoader imageLoader;

public NewsRowAdapter(Activity act, int resource, List<Item> arrayList) {
super(act, resource, arrayList);
this.activity = act;
this.row = resource;
this.items = arrayList;



imageLoader = ImageLoader.getInstance();
File cacheDir1 = StorageUtils.getCacheDirectory(activity);

ImageLoaderConfiguration config = new
ImageLoaderConfiguration.Builder(activity)
.maxImageWidthForMemoryCache(600)
.maxImageHeightForMemoryCache(400)
.httpConnectTimeout(5000)
.httpReadTimeout(20000)
.threadPoolSize(3)
.threadPriority(Thread.MIN_PRIORITY + 3)
.denyCacheImageMultipleSizesInMemory()
.memoryCache(new UsingFreqLimitedMemoryCache(20000)) // You can pass your own memory cache implementation
.discCache(new TotalSizeLimitedDiscCache(cacheDir1, 30000)) // You can pass your own disc cache implementation
.defaultDisplayImageOptions(DisplayImageOptions.createSimple())
.build();


ImageLoader.getInstance().init(config);
// imageLoader = ImageLoader;
//

options = new DisplayImageOptions.Builder()
.showStubImage(R.drawable.icon2x)
.showImageForEmptyUrl(R.drawable.icon2x).cacheInMemory()
.cacheOnDisc().build();
//imageLoader = ImageLoader.getInstance();

}

@Override
public Item getItem(int position)
{
return items.get(position);
}

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

@Override
public int getViewTypeCount()
{
return 3;
}

@Override
public int getItemViewType(int position)
{
Item item = items.get(position);
if (item.isHeader())
{
return TYPE_SECTION_HEADER;
}
else
{
return TYPE_LIST_ITEM;
}
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
View view = convertView;
ViewHolder holder;
if (view == null) {
LayoutInflater inflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(row, null);

holder = new ViewHolder();
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}

if ((items == null) || ((position + 1) > items.size()))
return view;

objBean = items.get(position);

holder.tvName = (TextView) view.findViewById(R.id.title);
holder.tvId = (TextView) view.findViewById(R.id.id);
holder.tvFlag = (TextView) view.findViewById(R.id.flag);
holder.tvimageurl=(TextView) view.findViewById(R.id.imageurl);
holder.tvGender = (ImageView) view.findViewById(R.id.image);
//holder.tvAge = (TextView) view.findViewById(R.id.tvage);
holder.pbar = (ProgressBar) view.findViewById(R.id.pbar);
if (holder.tvName != null && null != objBean.getName()
&& objBean.getName().trim().length() > 0) {
holder.tvName.setText(Html.fromHtml(objBean.getName()));
}
if (holder.tvId != null && null != objBean.getId()
&& objBean.getId().trim().length() > 0) {
holder.tvId.setText(Html.fromHtml(objBean.getId()));

}
if (holder.tvFlag != null && null != objBean.getFlag()
&& objBean.getFlag().trim().length() > 0) {
holder.tvFlag.setText(Html.fromHtml(objBean.getFlag()));

}

if (holder.tvimageurl != null && null != objBean.getGender()
&& objBean.getFlag().trim().length() > 0) {
holder.tvimageurl.setText(Html.fromHtml(objBean.getGender()));

}

//if (holder.tvBDate != null && null != objBean.getBirthdate()
// && objBean.getBirthdate().trim().length() > 0) {
// holder.tvBDate.setText(Html.fromHtml(objBean.getBirthdate()));
//}
if (holder.tvGender != null) {
if (null != objBean.getGender()
&& objBean.getGender().trim().length() > 0) {
final ProgressBar pbar = holder.pbar;


imageLoader.displayImage(objBean.getGender(), holder.tvGender,
options, new ImageLoadingListener() {

@Override
public void onLoadingComplete() {
pbar.setVisibility(View.INVISIBLE);

}


@Override
public void onLoadingFailed() {
pbar.setVisibility(View.INVISIBLE);
}


@Override
public void onLoadingStarted() {
pbar.setVisibility(View.INVISIBLE);

}
});

} else {
holder.tvGender.setImageResource(R.drawable.icon2x);
}
}


return view;
}

public class ViewHolder {
public TextView tvimageurl;
public TextView tvFlag;
public TextView tvId;
public ProgressBar pbar;
public TextView tvName, tvCity, tvBDate, tvAge;
ImageView tvGender;
}


}

需要帮助......

最佳答案

我在编写自己的 StickyHeader 时挣扎了很长时间,因为 StickyListHeaders git 不能完全满足我的需求。然而,StickyListHeaders 帮助我理解了如何最终让它工作,因此 StickyListHeaders 的作者值得一提。

许多事情必须放在一起才能使粘性 header 发挥作用。

首先声明如下

private TextView mStickyHeader;
private TextView mStickyHeader2;
private int mCurrentStickyHeaderSection;

onActivityCreated

@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
...
mCurrentStickyHeaderSection = -1;

mStickyHeader = (TextView) getView().findViewById(R.id.textview_sticky_header_section);
mStickyHeader2 = (TextView) getView().findViewById(R.id.textview_sticky_header_section_2);

mListView = (ListView) getView().findViewById(R.id.listView_with_sticky_headers);
mListView.setOnScrollListener(new OnScrollListener() {
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
updateStickyHeader(firstVisibleItem);
}

@Override
public void onScrollStateChanged(AbsListView arg0, int arg1) {
// TODO Auto-generated method stub
}
});

我假设您已经编写了带有节索引的 CustomAdapter,并且只会关注粘性 header 。

以下方法包含了拥有粘性 header 所需的所有内容。棘手的部分是确定 firstVisibleItem 是否为 header (pos = -1) 以及相应的部分。这部分可能需要您几次才能使其正常工作。

private void updateStickyHeader(int firstVisibleItem) {
// here is the tricky part. You have to determine pos and section
// pos is the position within a section pos = -1 means it's the header of the section
// you have to determine if firstVisibleItem is a header or not
// you also have to determine the section to which belongs the first item
int pos = whatIsThePositionOfTheItem[firstVisibleItem];
int section = whatIsTheSectionOfTheItem[firstVisibleItem];

if (section != mCurrentStickyHeaderSection) {
mStickyHeader.setText("Your_Previous_Section_Text");
mStickyHeader2.setText("Your_Next_Section_Text");
mCurrentStickyHeaderSection = section;
}

int stickyHeaderHeight = mStickyHeader.getHeight();
if (stickyHeaderHeight == 0) {
stickyHeaderHeight = mStickyHeader.getMeasuredHeight();
}

View SectionLastView = mListView.getChildAt(0);
if (SectionLastView != null && pos == -1 && SectionLastView.getBottom() <= stickyHeaderHeight) {
int lastViewBottom = SectionLastView.getBottom();
mStickyHeader.setTranslationY(lastViewBottom - stickyHeaderHeight);
mStickyHeader2.setTranslationY(lastViewBottom - stickyHeaderHeight + mStickyHeader.getHeight());
} else if (stickyHeaderHeight != 0) {
mStickyHeader.setTranslationY(0);
mStickyHeader2.setTranslationY(mStickyHeader.getHeight());
}
}

最后,布局必须包含一个 FrameLayout 并且应该看起来像那样

<?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" >

//this textview is just a global title of your listview if you need one but can be remove
<TextView
android:id="@+id/textview_title"
style="?android:attr/listSeparatorTextViewStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="6dp"
android:paddingRight="6dp"
android:textIsSelectable="false" />

<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" >

<TextView
android:id="@+id/textview_sticky_header_section"
style="?android:attr/listSeparatorTextViewStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="6dp"
android:paddingRight="6dp"
android:textIsSelectable="false" />

<TextView
android:id="@+id/textview_sticky_header_section_2"
style="?android:attr/listSeparatorTextViewStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="6dp"
android:paddingRight="6dp"
android:textIsSelectable="false" />
</FrameLayout>

<ListView
android:id="@+id/listView_with_sticky_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fastScrollEnabled="true"
android:longClickable="true" >
</ListView>

</LinearLayout>

更新

如评论中所问,这里是对 whatIsThePositionOfTheItemwhatIsTheSectionOfTheItem 的解释。这些方法必须返回给定项目的 positionsection

在我的例子中,它非常简单,我的数据已经包含了 sectionposition。实际上,我正在显示文本,该文本以 sectionposition 开头。所以我只是解析该文本以确定 sectionposition

对于其他人,很难给出示例,因为这实际上取决于您要显示的内容。但长话短说 whatIsThePositionOfTheItemwhatIsTheSectionOfTheItem 必须返回给定项目的位置和部分。您可能需要用列表中每个项目的 positionsection 填充表格,并获取 positionsection 来自该表。

关于android - 如何向我的 ListView 添加粘性 header ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16457177/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com