最近公司要做列表上滑,然后顶部固定屏幕上方的功能,在网上找了许久,也找到了几个蛮好的例子,做了两个demo,所以整理下,分享一下,同时做个笔记。
一,第一种实现方式:
原理是通过listView添加头部,然后当滑动到顶部将原本隐藏的头部布局显示出来,直接上代码
先看下整体布局
1.先建立布局文件
下面是include_floatbar.xml布局
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="100dp" android:layout_alignParentTop="true" android:background="#00f"> <TextView android:text="浮动栏" android:gravity="center" android:layout_width="match_parent" android:layout_height="100dp"/> </FrameLayout>
下面是listitem_headview.xml
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="100dp" android:layout_alignParentTop="true" android:background="#00f"> <TextView android:text="头部" android:gravity="center" android:layout_width="match_parent" android:layout_height="100dp"/> </FrameLayout>
3.下面是主界面布局
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <ListView android:id="@+id/lv" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_alignParentTop="true" android:fadingEdge="none"/> <FrameLayout android:id="@+id/float_bar" android:layout_width="match_parent" android:layout_height="wrap_content" android:visibility="gone"> <include layout="@layout/include_floatbar"/> </FrameLayout> </RelativeLayout>
4.Adater其实自己可以随便写下
public class MyAdapter extends BaseAdapter { List<String> data; Context context; public MyAdapter(List<String> data, Context context) { this.data = data; this.context = context; } @Override public int getCount() { return data.size(); } @Override public Object getItem(int position) { return data.get(position); } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { View view = LayoutInflater.from(context).inflate(R.layout.item_taobao_product,null); TextView tvName = view.findViewById(R.id.tv_title); tvName.setText(data.get(position)); return view; } }
5.主界面代码:
public class MainActivity extends AppCompatActivity { private Context mContext; private ListView mListView; private View mHeadView; private View mFloatBarInLvHeader; private View mFloatBar; MyAdapter adpater; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mContext = this; mListView = (ListView) findViewById(R.id.lv); // ListView 顶部隐藏的浮动栏 mFloatBar = findViewById(R.id.float_bar); // ListView 第一个头部控件(效果图中的 色区域) mHeadView = LayoutInflater.from(mContext).inflate(R.layout.listitem_headview, mListView, false); mListView.addHeaderView(mHeadView); // ListView 第二个头部控件(浮动栏) mFloatBarInLvHeader = LayoutInflater.from(mContext).inflate(R.layout.include_floatbar, mListView, false); mListView.addHeaderView(mFloatBarInLvHeader); List<String> data = new ArrayList<>(100); for (int i = 0; i < 100; ++i) { data.add(String.valueOf(i)); } adpater = new MyAdapter(data,this); mListView.setAdapter(adpater); // 监听 ListView 滑动事件 mListView.setOnScrollListener(new AbsListView.OnScrollListener() { @Override public void onScrollStateChanged(AbsListView view, int scrollState) { } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { /* 判断ListView头部中的浮动栏(mFloatBarInLvHeader)当前是否可见 * 来决定隐藏或显示浮动栏(mFloatBar)*/ if (firstVisibleItem >= 1) { mFloatBar.setVisibility(View.VISIBLE); } else { mFloatBar.setVisibility(View.GONE); } } }); } }运行下代码应该效果就出来,但是有个问题需要注意:主界面要用RelativeLayout或者FrameLayout,千万不要用LinearLayout,因为LinearLayout的子控件占了空间,你隐藏时界面会明显的跳动,因为它改变了布局的大小 ,而RelativeLayout和FrameLayout不会。