- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我有一个 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>
更新
如评论中所问,这里是对 whatIsThePositionOfTheItem
和 whatIsTheSectionOfTheItem
的解释。这些方法必须返回给定项目的 position
和 section
。
在我的例子中,它非常简单,我的数据已经包含了 section
和 position
。实际上,我正在显示文本,该文本以 section
和 position
开头。所以我只是解析该文本以确定 section
和 position
。
对于其他人,很难给出示例,因为这实际上取决于您要显示的内容。但长话短说 whatIsThePositionOfTheItem
和 whatIsTheSectionOfTheItem
必须返回给定项目的位置和部分。您可能需要用列表中每个项目的 position
和 section
填充表格,并获取 position
和 section
来自该表。
关于android - 如何向我的 ListView 添加粘性 header ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16457177/
我最近在/ drawable中添加了一些.gifs,以便可以将它们与按钮一起使用。这个工作正常(没有错误)。现在,当我重建/运行我的应用程序时,出现以下错误: Error: Gradle: Execu
Android 中有返回内部存储数据路径的方法吗? 我有 2 部 Android 智能手机(Samsung s2 和 s7 edge),我在其中安装了一个应用程序。我想使用位于这条路径中的 sqlit
这个问题在这里已经有了答案: What's the difference between "?android:" and "@android:" in an android layout xml f
我只想知道 android 开发手机、android 普通手机和 android root 手机之间的实际区别。 我们不能从实体店或除 android marketplace 以外的其他地方购买开发手
自Gradle更新以来,我正在努力使这个项目达到标准。这是一个团队项目,它使用的是android-apt插件。我已经进行了必要的语法更改(编译->实现和apt->注释处理器),但是编译器仍在告诉我存在
我是android和kotlin的新手,所以请原谅要解决的一个非常简单的问题! 我已经使用导航体系结构组件创建了一个基本应用程序,使用了底部的导航栏和三个导航选项。每个导航选项都指向一个专用片段,该片
我目前正在使用 Facebook official SDK for Android . 我现在正在使用高级示例应用程序,但我不知道如何让它获取应用程序墙/流/状态而不是登录的用户。 这可能吗?在那种情
我在下载文件时遇到问题, 我可以在模拟器中下载文件,但无法在手机上使用。我已经定义了上网和写入 SD 卡的权限。 我在服务器上有一个 doc 文件,如果用户单击下载。它下载文件。这在模拟器中工作正常但
这个问题在这里已经有了答案: What is the difference between gravity and layout_gravity in Android? (22 个答案) 关闭 9
任何人都可以告诉我什么是 android 缓存和应用程序缓存,因为当我们谈论缓存清理应用程序时,它的作用是,缓存清理概念是清理应用程序缓存还是像内存管理一样主存储、RAM、缓存是不同的并且据我所知,缓
假设应用程序 Foo 和 Eggs 在同一台 Android 设备上。任一应用程序都可以获取设备上所有应用程序的列表。一个应用程序是否有可能知道另一个应用程序是否已经运行以及运行了多长时间? 最佳答案
我有点困惑,我只看到了从 android 到 pc 或者从 android 到 pc 的例子。我需要制作一个从两部手机 (android) 连接的 android 应用程序进行视频聊天。我在想,我知道
用于使用 Android 以编程方式锁定屏幕。我从 Stackoverflow 之前关于此的问题中得到了一些好主意,并且我做得很好,但是当我运行该代码时,没有异常和错误。而且,屏幕没有锁定。请在这段代
文档说: android:layout_alignParentStart If true, makes the start edge of this view match the start edge
我不知道这两个属性和高度之间的区别。 以一个TextView为例,如果我将它的layout_width设置为wrap_content,并将它的width设置为50 dip,会发生什么情况? 最佳答案
这两个属性有什么关系?如果我有 android:noHistory="true",那么有 android:finishOnTaskLaunch="true" 有什么意义吗? 最佳答案 假设您的应用中有
我是新手,正在尝试理解以下 XML 代码: 查看 developer.android.com 上的文档,它说“starStyle”是 R.attr 中的常量, public static final
在下面的代码中,为什么当我设置时单选按钮的外观会发生变化 android:layout_width="fill_parent" 和 android:width="fill_parent" 我说的是
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 9
假设我有一个函数 fun myFunction(name:String, email:String){},当我调用这个函数时 myFunction('Ali', 'ali@test.com ') 如何
我是一名优秀的程序员,十分优秀!