一:先来效果图吧、
二:实现步骤:
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地址奉上:点击打开链接