Android ScrollView与ListView,GridView共存冲突解决方案
我们在真实项目中通常会遇到ListView或者GridView嵌套在ScrollView中问题。但是做的时候会发现,一旦两者进行嵌套,即会发生冲突。得不到我们希望的效果。由于ListView和GridView本身都继承于ScrollView,一旦在ScrollView中嵌套ScrollView,那么里面的ScrollView高度计算就会出现问题。我们也就无法得到想要的效果。下面进入正题,我们将分别讨论ScrollView中嵌套ListView和FGridView的情况:
核心解决方案: 重写ListView或者GridView的OnMesure 方法:
@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {// TODO Auto-generated method stubint expandSpec = MeasureSpec.makeMeasureSpec( Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST); super.onMeasure(widthMeasureSpec, expandSpec);}
一、ScrollView中嵌套ListView
BlogScrollViewActivity.java代码:
package com.csdn.blog.scrollview;import android.app.Activity;import android.os.Bundle;import android.view.View;import android.view.ViewGroup;import android.widget.ArrayAdapter;import android.widget.BaseAdapter;import android.widget.GridView;import android.widget.ImageView;import android.widget.LinearLayout;import android.widget.ListView;import android.widget.ScrollView;import android.widget.LinearLayout.LayoutParams;import android.widget.TextView;public class BlogScrollViewActivity extends Activity { /** Called when the activity is first created. *///MyGridView grid;ImageView image;ScrollView scroll;String[] texts=new String[]{"无线","通话设置","声音","显示","位置", "应用","账户","隐私权","存储","语言","游戏","娱乐","电影","音乐", "辅助功能","日期"};/*ArrayAdapter<String> adapter;*/TestListView list;LinearLayout.LayoutParams lp; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); init(); } void init(){ list=(TestListView)findViewById(R.id.list); image=(ImageView)findViewById(R.id.image); list.setAdapter(new GridAdapter(this)); scroll=(ScrollView)findViewById(R.id.scroll); scroll.requestChildFocus(image, null); } private class GridAdapter extends BaseAdapter{ Activity context; public GridAdapter(Activity context){ this.context=context; }@Overridepublic int getCount() {// TODO Auto-generated method stubreturn texts.length;}@Overridepublic Object getItem(int position) {// TODO Auto-generated method stubreturn null;}@Overridepublic long getItemId(int position) {// TODO Auto-generated method stubreturn 0;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {// TODO Auto-generated method stubViewHolder holder=null;if(convertView==null){convertView=context.getLayoutInflater().inflate(R.layout.item, null);holder=new ViewHolder();holder.text=(TextView)convertView.findViewById(R.id.grid_text);convertView.setTag(holder);}else{holder=(ViewHolder)convertView.getTag();}holder.text.setText(texts[position]);return convertView;}class ViewHolder {TextView text;} }}
TestListView.java代码如下:
package com.csdn.blog.scrollview;import android.content.Context;import android.util.AttributeSet;import android.view.View.MeasureSpec;import android.widget.ListView;public class TestListView extends ListView{public TestListView(Context context) {super(context);// TODO Auto-generated constructor stub}public TestListView(Context context, AttributeSet attrs) {super(context, attrs);// TODO Auto-generated constructor stub}public TestListView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);// TODO Auto-generated constructor stub}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {// TODO Auto-generated method stubint expandSpec = MeasureSpec.makeMeasureSpec( Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST); super.onMeasure(widthMeasureSpec, expandSpec);}}
main.xml代码:
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" android:background="#FFFFFF" > <ScrollView android:layout_height="fill_parent" android:layout_width="fill_parent" android:fadingEdgeLength="0dp" android:scrollbars="none" android:id="@+id/scroll"> <LinearLayout android:layout_height="fill_parent" android:layout_width="fill_parent" android:orientation="vertical" > <ImageView android:id="@+id/image" android:layout_height="150dp" android:layout_width="fill_parent" android:padding="2dp" android:scaleType="centerCrop" android:src="@drawable/fruit"
/> <com.csdn.blog.scrollview.TestListView android:id="@+id/list" android:layout_height="fill_parent" android:layout_width="fill_parent" android:fadingEdgeLength="0dp" android:scrollbars="none" /> </LinearLayout> </ScrollView>
</LinearLayout>
效果图如下:
这里我的布局方式是上面一张图片,下面放置listView。
对于此种布局方式,可以通过另外一种方式避免此问题。由于ListView有addHeadView()方法,那么我们可以直接将上面想加入的View通过 getLayoutInflater().inflate(this,R.layout.***) 加入到ListView的顶部即可。
二、ScrollView中嵌套GridView的解决方案。
ScrollView中嵌套GridView ,最简单的方法就是重写GridView方法,使其在绘制时重新计算GridView高度
MyGridView.java代码如下:
package com.csdn.blog.scrollview;import android.content.Context;import android.util.AttributeSet;import android.widget.GridView;public class MyGridView extends GridView{public MyGridView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);// TODO Auto-generated constructor stub}public MyGridView(Context context, AttributeSet attrs) {super(context, attrs);// TODO Auto-generated constructor stub}public MyGridView(Context context) {super(context);// TODO Auto-generated constructor stub}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {// TODO Auto-generated method stubint expandSpec = MeasureSpec.makeMeasureSpec( Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST); super.onMeasure(widthMeasureSpec, expandSpec); }}
main.xml代码如下:
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" android:background="#FFFFFF" > <ScrollView android:layout_height="fill_parent" android:layout_width="fill_parent" android:fadingEdgeLength="0dp" android:scrollbars="none" android:id="@+id/scroll"> <LinearLayout android:layout_height="fill_parent" android:layout_width="fill_parent" android:orientation="vertical" > <ImageView android:id="@+id/image" android:layout_height="150dp" android:layout_width="fill_parent" android:padding="2dp" android:scaleType="centerCrop" android:src="@drawable/fruit" /> <com.csdn.blog.scrollview.MyGridView android:layout_marginTop="10dp" android:id="@+id/grid" android:layout_height="fill_parent" android:layout_width="fill_parent" android:fadingEdgeLength="0dp" android:scrollbars="none" android:numColumns="3" /> </LinearLayout> </ScrollView></LinearLayout>
主类主要就是GridVIew数据绑定。简单贴下代码:
package com.csdn.blog.scrollview;import android.app.Activity;import android.os.Bundle;import android.view.View;import android.view.ViewGroup;import android.widget.ArrayAdapter;import android.widget.BaseAdapter;import android.widget.GridView;import android.widget.ImageView;import android.widget.LinearLayout;import android.widget.ListView;import android.widget.ScrollView;import android.widget.LinearLayout.LayoutParams;import android.widget.TextView;public class BlogScrollViewActivity extends Activity { /** Called when the activity is first created. */MyGridView grid;ImageView image;ScrollView scroll;String[] texts=new String[]{"无线","通话设置","声音","显示","位置", "应用","账户","隐私权","存储","语言","游戏","娱乐","电影","音乐", "辅助功能","日期"};ArrayAdapter<String> adapter;LinearLayout.LayoutParams lp; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); init(); } void init(){ image=(ImageView)findViewById(R.id.image); grid=(MyGridView)findViewById(R.id.grid); grid.setAdapter(new GridAdapter(this)); scroll=(ScrollView)findViewById(R.id.scroll); scroll.requestChildFocus(image, null); } private class GridAdapter extends BaseAdapter{ Activity context; public GridAdapter(Activity context){ this.context=context; }@Overridepublic int getCount() {// TODO Auto-generated method stubreturn texts.length;}@Overridepublic Object getItem(int position) {// TODO Auto-generated method stubreturn null;}@Overridepublic long getItemId(int position) {// TODO Auto-generated method stubreturn 0;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {// TODO Auto-generated method stubViewHolder holder=null;if(convertView==null){convertView=context.getLayoutInflater().inflate(R.layout.item, null);holder=new ViewHolder();holder.image=(ImageView)convertView.findViewById(R.id.grid_image);holder.text=(TextView)convertView.findViewById(R.id.grid_text);convertView.setTag(holder);}else{holder=(ViewHolder)convertView.getTag();}holder.image.setImageResource(R.drawable.meinv);holder.text.setText(texts[position]);return convertView;}class ViewHolder {ImageView image;TextView text;} }}
上述代码中 scroll.requestChildFocus(image, null); 此句主要是修复了程序进入时GridView会滑动到顶端的小bug。
效果图如下: