一:先来效果图吧、
二:实现步骤:
1.主Activity的布局、
<?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:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.wergr.myapplication.MainActivity" tools:ignore="Orientation"> <com.example.wergr.myapplication.MyScrollView android:id="@+id/scroller" android:layout_width="fill_parent" android:layout_height="fill_parent" android:scrollbars="none"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <com.example.wergr.myapplication.MyListView android:id="@+id/list_top" android:layout_width="wrap_content" android:layout_height="wrap_content"> </com.example.wergr.myapplication.MyListView> <ImageView android:layout_width="match_parent" android:layout_height="100dp" android:scaleType="fitXY" android:src="@mipmap/meinv" /> <com.example.wergr.myapplication.MyListView android:id="@+id/list_button" android:layout_width="wrap_content" android:layout_height="wrap_content"></com.example.wergr.myapplication.MyListView> </LinearLayout> </com.example.wergr.myapplication.MyScrollView> </RelativeLayout>
2.自定义的Scrollview、
package com.example.wergr.myapplication; import android.content.Context; import android.util.AttributeSet; import android.view.MotionEvent; import android.widget.ScrollView; /** * Created by wergr on 2018/5/4. * 自定义scrollview */ public class MyScrollView extends ScrollView { public MyScrollView(Context context) { super(context); } public MyScrollView(Context context, AttributeSet attrs) { super(context, attrs); } private ScrollViewListener scrollViewListener = null; public void setScrollViewListener(ScrollViewListener scrollViewListener) { this.scrollViewListener = scrollViewListener; } private boolean allowChildViewScroll = true; public void setAllowChildViewScroll(boolean allowChildViewScroll) { this.allowChildViewScroll = allowChildViewScroll; } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { if(!allowChildViewScroll){ return true; } return super.onInterceptTouchEvent(ev); } @Override protected void onScrollChanged(int x, int y, int oldx, int oldy) { super.onScrollChanged(x, y, oldx, oldy); if (scrollViewListener != null) { scrollViewListener.onScrollChanged(this, x, y, oldx, oldy); } } public interface ScrollViewListener { void onScrollChanged(ScrollView scrollView,int x, int y, int oldx, int oldy); } }3.自定义的ListView
package com.example.wergr.myapplication; import android.content.Context; import android.util.AttributeSet; import android.view.MotionEvent; import android.widget.ListView; import android.widget.ScrollView; /** * Created by wergr on 2018/5/4. * 自定义的LisvtView */ public class MyListView extends ListView { private ScrollView scrollView; private boolean notAllowParentScroll = true; public void setNotAllowParentScroll(boolean notAllowParentScroll) { this.notAllowParentScroll = notAllowParentScroll; } public void setScrollView(ScrollView scrollView) { this.scrollView = scrollView; } public MyListView(Context context) { super(context); } public MyListView(Context context, AttributeSet attrs) { super(context, attrs); } @Override public boolean dispatchTouchEvent(MotionEvent event) { if(notAllowParentScroll){ switch(event.getAction()){ case MotionEvent.ACTION_DOWN: scrollView.requestDisallowInterceptTouchEvent(false);//如果为true的话滑动不流畅,等滑两次才开始改变位置 break; case MotionEvent.ACTION_UP: scrollView.requestDisallowInterceptTouchEvent(false);//同样为true滑动不流畅,得滑动两次才改变位置 break; } } return super.dispatchTouchEvent(event); } }
4.adapter(这里为了区分两个listview所以写了两个listview,其实一个就可以)、
(1):第一个adapter、
package com.example.wergr.myapplication; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.TextView; import java.util.List; /** * Created by wergr on 2018/5/4. */ public class MyAdapter extends BaseAdapter { private List<String> list; private LayoutInflater inflater; private Context ctx; public MyAdapter(List<String> list, Context ctx) { this.list = list; this.ctx = ctx; inflater =LayoutInflater.from(ctx); } @Override public int getCount() { return list.size(); } @Override public Object getItem(int position) { return list.get(position); } @Override public long getItemId(int position) { return 0; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder; if(convertView==null){ convertView = inflater.inflate(R.layout.list_item_top,parent,false); holder = new ViewHolder(); holder.tv = (TextView) convertView.findViewById(R.id.text_top); convertView.setTag(holder); }else{ holder = (ViewHolder) convertView.getTag(); } holder.tv.setText(list.get(position)); return convertView; } class ViewHolder{ public TextView tv; } }
(2):第一个适adapter的item布局、
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/text_top" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:text="这是第一个listview" android:textColor="#232323" android:textSize="18dp" /> </RelativeLayout>
(3):第二个adapter、
package com.example.wergr.myapplication; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.TextView; import java.util.List; /** * Created by wergr on 2018/5/4. */ public class MyAdapterbutton extends BaseAdapter { private List<String> list; private LayoutInflater inflater; private Context ctx; public MyAdapterbutton(List<String> list, Context ctx) { this.list = list; this.ctx = ctx; inflater =LayoutInflater.from(ctx); } @Override public int getCount() { return list.size(); } @Override public Object getItem(int position) { return list.get(position); } @Override public long getItemId(int position) { return 0; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder; if(convertView==null){ convertView = inflater.inflate(R.layout.list_item_button,parent,false); holder = new ViewHolder(); holder.tv = (TextView) convertView.findViewById(R.id.text_button); convertView.setTag(holder); }else{ holder = (ViewHolder) convertView.getTag(); } holder.tv.setText(list.get(position)); return convertView; } class ViewHolder{ public TextView tv; } }
(4):第二个adapter的布局、
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/text_button" android:layout_width="match_parent" android:layout_height="match_parent" android:text="这是第二个listview" android:gravity="center" android:textColor="#232323" android:textSize="18dp" /> </RelativeLayout>
5.主Activity的核心代码、
package com.example.wergr.myapplication; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.widget.AbsListView; import android.widget.ListAdapter; import android.widget.ListView; import android.widget.ScrollView; import java.util.ArrayList; import java.util.List; public class MainActivity extends AppCompatActivity implements View.OnTouchListener { private MyListView list_top, list_button; private MyAdapter adapter; private MyAdapterbutton adapterbutton; private MyScrollView scroller; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initlayout(); } private void initlayout() { scroller = (MyScrollView) findViewById(R.id.scroller); list_top = (MyListView) findViewById(R.id.list_top); list_button = (MyListView) findViewById(R.id.list_button); scroller.setOnTouchListener(this); adapter = getAdapter("第一个listview"); list_top.setAdapter(adapter); setListViewHeightBasedOnChildren(list_top); list_top.setScrollView(scroller); adapterbutton = getAdapterbutton("第二个listview"); list_button.setAdapter(adapterbutton); setListViewHeightBasedOnChildren(list_button); list_button.setScrollView(scroller); list_top.setOnScrollListener(new AbsListView.OnScrollListener() { @Override public void onScrollStateChanged(AbsListView view, int scrollState) { switch (scrollState) { case AbsListView.OnScrollListener.SCROLL_STATE_IDLE: // 判断滚动到底部,scrollview滚动,listview1滚动屏蔽 if (view.getLastVisiblePosition() == (view.getCount() - 1)) { list_top.setNotAllowParentScroll(false); scroller.setAllowChildViewScroll(false); } break; } } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { } }); list_button.setOnScrollListener(new AbsListView.OnScrollListener() { @Override public void onScrollStateChanged(AbsListView view, int scrollState) { switch (scrollState) { case AbsListView.OnScrollListener.SCROLL_STATE_IDLE: // 判断滚动到顶部,listview2开始滚动,scrollview滚动屏蔽 if (view.getFirstVisiblePosition() == 0) { scroller.setAllowChildViewScroll(false); list_button.setNotAllowParentScroll(false); scroller.requestDisallowInterceptTouchEvent(true); } break; } } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { } }); scroller.setScrollViewListener(new MyScrollView.ScrollViewListener() { @Override public void onScrollChanged(ScrollView scrollView, int x, int y, int oldx, int oldy) { int[] listview2location = new int[2]; list_button.getLocationOnScreen(listview2location); int[] location1 = new int[2]; scroller.getLocationOnScreen(location1); //在scrollview滚动过程中,如果listview2正好填满整个屏幕,此时需要屏蔽scrollview的滚动 if (listview2location[1] == location1[1]) { list_button.setNotAllowParentScroll(true); scroller.setAllowChildViewScroll(true); return; } int[] listview1location = new int[2]; list_top.getLocationOnScreen(listview1location); //在scrollview滚动过程中,如果listview1正好填满整个屏幕,此时需要屏蔽scrollview的滚动 if (listview1location[1] == location1[1]) { scroller.setAllowChildViewScroll(true); list_top.setNotAllowParentScroll(true); return; } //在scrollview滚动过程中,屏蔽listview的滚动 scroller.setAllowChildViewScroll(false); } }); } /** * 动态设置ListView的高度 * * @param listView */ public static void setListViewHeightBasedOnChildren(ListView listView) { if (listView == null) return; ListAdapter listAdapter = listView.getAdapter(); if (listAdapter == null) { // pre-condition return; } int totalHeight = 0; for (int i = 0; i < listAdapter.getCount(); i++) { View listItem = listAdapter.getView(i, null, listView); listItem.measure(0, 0); totalHeight += listItem.getMeasuredHeight(); } ViewGroup.LayoutParams params = listView.getLayoutParams(); params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1)); listView.setLayoutParams(params); } @Override public boolean onTouch(View v, MotionEvent event) { //屏蔽listview的滚动造成listview switch (event.getAction()) { case MotionEvent.ACTION_DOWN: scroller.setAllowChildViewScroll(false); break; case MotionEvent.ACTION_UP: scroller.setAllowChildViewScroll(true); break; } return false; } private MyAdapter getAdapter(String str) { List<String> list = new ArrayList<>(); for (int i = 0; i < 10; i++) { list.add(str); } return new MyAdapter(list, this); } private MyAdapterbutton getAdapterbutton(String str) { List<String> list = new ArrayList<>(); for (int i = 0; i < 20; i++) { list.add(str); } return new MyAdapterbutton(list, this); } }
注:因为scrollview嵌套listview会导致冲突,解决办法是这个方法:
setListViewHeightBasedOnChildren();
----------------------最后把demo地址奉上:点击打开链接