Dan*_*les 37 android listview scrollview ios
我的具体问题是:如何实现这样的效果:http://youtu.be/EJm7subFbQI
反弹效果并不重要,但我需要标题的"粘性"效果.我从哪里开始?,我能以什么为基础?我需要一些我可以在API 8上实现的东西.
谢谢.
Kyl*_*egg 48
这个问题已经存在一些解决方案.您所描述的是节标题,并且在Android中被称为粘性节标题.
编辑:有一些空闲时间添加完整工作示例的代码.相应地编辑了答案.
对于那些不想使用第三方代码(或者不能直接使用它,例如在Xamarin中)的人来说,这可以通过手工轻松完成.我们的想法是使用另一个ListView作为标题.此列表视图仅包含标题项.它不会被用户滚动(setEnabled(false)),但会根据主列表的滚动从代码滚动.所以你将有两个列表 - headerListview和mainListview,以及两个相应的适配器headerAdapter和mainAdapter.headerAdapter仅返回节视图,而mainAdapter支持两种视图类型(节和项).您将需要一个方法,该方法在主列表中占据一个位置并在区段列表中返回相应的位置.
主要活动
public class MainActivity extends AppCompatActivity {
public static final int TYPE_SECTION = 0;
public static final int TYPE_ITEM = 1;
ListView mainListView;
ListView headerListView;
MainAdapter mainAdapter;
HeaderAdapter headerAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mainListView = (ListView)findViewById(R.id.list);
headerListView = (ListView)findViewById(R.id.header);
mainAdapter = new MainAdapter();
headerAdapter = new HeaderAdapter();
headerListView.setEnabled(false);
headerListView.setAdapter(headerAdapter);
mainListView.setAdapter(mainAdapter);
mainListView.setOnScrollListener(new AbsListView.OnScrollListener(){
@Override
public void onScrollStateChanged(AbsListView view, int scrollState){
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
// this should return an index in the headers list, based one the index in the main list. The logic for this is highly dependent on your data.
int pos = mainAdapter.getSectionIndexForPosition(firstVisibleItem);
// this makes sure our headerListview shows the proper section (the one on the top of the mainListview)
headerListView.setSelection(pos);
// this makes sure that headerListview is scrolled exactly the same amount as the mainListview
if(mainAdapter.getItemViewType(firstVisibleItem + 1) == TYPE_SECTION){
headerListView.setSelectionFromTop(pos, mainListView.getChildAt(0).getTop());
}
}
});
}
public class MainAdapter extends BaseAdapter{
int count = 30;
@Override
public int getItemViewType(int position){
if((float)position / 10 == (int)((float)position/10)){
return TYPE_SECTION;
}else{
return TYPE_ITEM;
}
}
@Override
public int getViewTypeCount(){ return 2; }
@Override
public int getCount() { return count - 1; }
@Override
public Object getItem(int position) { return null; }
@Override
public long getItemId(int position) { return position; }
public int getSectionIndexForPosition(int position){ return position / 10; }
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = getLayoutInflater().inflate(R.layout.item, parent, false);
position++;
if(getItemViewType(position) == TYPE_SECTION){
((TextView)v.findViewById(R.id.text)).setText("SECTION "+position);
}else{
((TextView)v.findViewById(R.id.text)).setText("Item "+position);
}
return v;
}
}
public class HeaderAdapter extends BaseAdapter{
int count = 5;
@Override
public int getCount() { return count; }
@Override
public Object getItem(int position) { return null; }
@Override
public long getItemId(int position) { return position; }
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = getLayoutInflater().inflate(R.layout.item, parent, false);
((TextView)v.findViewById(R.id.text)).setText("SECTION "+position*10);
return v;
}
}
}
Run Code Online (Sandbox Code Playgroud)
这里有几点需要注意.我们不希望在主视图列表中显示第一部分,因为它会产生重复(它已经显示在标题中).为避免这种情况,请在mainAdapter.getCount()中:
return actualCount - 1;
Run Code Online (Sandbox Code Playgroud)
并确保getView()方法的第一行是
position++;
Run Code Online (Sandbox Code Playgroud)
这样,您的主列表将呈现所有单元格,但第一个单元格.
另一件事是你要确保headerListview的高度与列表项的高度相匹配.在此示例中,高度是固定的,但如果您的项目高度未设置为dp中的精确值,则可能会非常棘手.有关如何解决此问题,请参阅此答案:https://stackoverflow.com/a/41577017/291688
主要布局
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin">
<ListView
android:id="@+id/header"
android:layout_width="match_parent"
android:layout_height="48dp"/>
<ListView
android:id="@+id/list"
android:layout_below="@+id/header"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
Run Code Online (Sandbox Code Playgroud)
项目/标题布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="48dp">
<TextView
android:id="@+id/text"
android:gravity="center_vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</LinearLayout>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
50477 次 |
| 最近记录: |