NestedScrollView 之 ScrollView 巢狀 ListView
阿新 • • 發佈:2018-12-29
Anroid Studio 新建一個工程之後,預設繼承AppCompatActivity,
MainActivity 佈局如下
main.layout
<?xml version="1.0" encoding="utf-8"?> <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:fitsSystemWindows="true" tools:context="com.yungcs.project.myapplication.MainActivity"> s <android.support.design.widget.AppBarLayout android:id="@+id/app_bar" android:fitsSystemWindows="true" android:layout_height="@dimen/app_bar_height" android:layout_width="match_parent" android:theme="@style/AppTheme.AppBarOverlay"> <android.support.design.widget.CollapsingToolbarLayout android:id="@+id/toolbar_layout" android:fitsSystemWindows="true" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_scrollFlags="scroll|exitUntilCollapsed" app:contentScrim="?attr/colorPrimary"> <android.support.v7.widget.Toolbar android:id="@+id/toolbar" android:layout_height="?attr/actionBarSize" android:layout_width="match_parent" app:layout_collapseMode="pin" app:popupTheme="@style/AppTheme.PopupOverlay" /> </android.support.design.widget.CollapsingToolbarLayout> </android.support.design.widget.AppBarLayout> <include layout="@layout/content_scrolling" /> <android.support.design.widget.FloatingActionButton android:id="@+id/fab" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="@dimen/fab_margin" app:layout_anchor="@id/app_bar" app:layout_anchorGravity="bottom|end" android:src="@android:drawable/ic_dialog_email" /> </android.support.design.widget.CoordinatorLayout>
content_scrolling.layout
<?xml version="1.0" encoding="utf-8"?> <!-- android.support.v4.widget.NestedScrollView--> <com.yungcs.project.myapplication.MyNestedScrollView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" app:layout_behavior="@string/appbar_scrolling_view_behavior" tools:showIn="@layout/activity_scrolling" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.yungcs.project.myapplication.ScrollingActivity"> <android.support.v7.widget.RecyclerView android:id="@+id/recyclerView" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior" /> <com.yungcs.project.myapplication.NestedListView android:id="@+id/phone_list" android:layout_width="match_parent" android:layout_height="wrap_content" > </com.yungcs.project.myapplication.NestedListView> </com.yungcs.project.myapplication.MyNestedScrollView>
重寫ListView
package com.yungcs.project.myapplication; import android.content.Context; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.widget.AbsListView; import android.widget.ListAdapter; import android.widget.ListView; /** * Created by yungcs on 2016/1/7. */ public class NestedListView extends ListView implements View.OnTouchListener, AbsListView.OnScrollListener { private int listViewTouchAction; private static final int MAXIMUM_LIST_ITEMS_VIEWABLE = 99; public NestedListView(Context context, AttributeSet attrs) { super(context, attrs); listViewTouchAction = -1; setOnScrollListener(this); setOnTouchListener(this); } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { if (getAdapter() != null && getAdapter().getCount() > MAXIMUM_LIST_ITEMS_VIEWABLE) { if (listViewTouchAction == MotionEvent.ACTION_MOVE) { scrollBy(0, -1); } } } @Override public void onScrollStateChanged(AbsListView view, int scrollState) { } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); int newHeight = 0; final int heightMode = MeasureSpec.getMode(heightMeasureSpec); int heightSize = MeasureSpec.getSize(heightMeasureSpec); if (heightMode != MeasureSpec.EXACTLY) { ListAdapter listAdapter = getAdapter(); if (listAdapter != null && !listAdapter.isEmpty()) { int listPosition = 0; for (listPosition = 0; listPosition < listAdapter.getCount() && listPosition < MAXIMUM_LIST_ITEMS_VIEWABLE; listPosition++) { View listItem = listAdapter.getView(listPosition, null, this); // now it will not throw a NPE if listItem is a ViewGroup // instance if (listItem instanceof ViewGroup) { listItem.setLayoutParams(new LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); } listItem.measure(widthMeasureSpec, heightMeasureSpec); newHeight += listItem.getMeasuredHeight(); } newHeight += getDividerHeight() * listPosition; } if ((heightMode == MeasureSpec.AT_MOST) && (newHeight > heightSize)) { if (newHeight > heightSize) { newHeight = heightSize; } } } else { newHeight = getMeasuredHeight(); } setMeasuredDimension(getMeasuredWidth(), newHeight); } public boolean onTouch(View v, MotionEvent event) { if (getAdapter() != null && getAdapter().getCount() > MAXIMUM_LIST_ITEMS_VIEWABLE) { if (listViewTouchAction == MotionEvent.ACTION_MOVE) { scrollBy(0, 1); } } return false; } }
效果圖如下(僅僅供參考,實物請看程式碼效果)
程式碼Demo下載: