您的位置:首页 > 移动开发 > Android开发

Android ScrollView与ListView,GridView共存冲突解决方案

2016-03-07 09:42 531 查看
我们在真实项目中通常会遇到ListView或者GridView嵌套在ScrollView中问题。但是做的时候会发现,一旦两者进行嵌套,即会发生冲突。得不到我们希望的效果。由于ListView和GridView本身都继承于ScrollView,一旦在ScrollView中嵌套ScrollView,那么里面的ScrollView高度计算就会出现问题。我们也就无法得到想要的效果。下面进入正题,我们将分别讨论ScrollView中嵌套ListView和FGridView的情况:

 

     核心解决方案: 重写ListView或者GridView的OnMesure 方法:

  

[java] 

@Override 

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 

    // TODO Auto-generated method stub 

    int expandSpec = MeasureSpec.makeMeasureSpec(  

               Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);  

     

    super.onMeasure(widthMeasureSpec, expandSpec); 



 

 

    一、ScrollView中嵌套ListView

  BlogScrollViewActivity.java代码:

[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; 

        } 

        @Override 

        public int getCount() { 

            // TODO Auto-generated method stub 

            return texts.length; 

        } 

 

        @Override 

        public Object getItem(int position) { 

            // TODO Auto-generated method stub 

            return null; 

        } 

 

        @Override 

        public long getItemId(int position) { 

            // TODO Auto-generated method stub 

            return 0; 

        } 

 

        @Override 

        public View getView(int position, View convertView, ViewGroup parent) { 

            // TODO Auto-generated method stub 

            ViewHolder 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代码如下:

[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 

    } 

    @Override 

    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 

        // TODO Auto-generated method stub 

        int expandSpec = MeasureSpec.makeMeasureSpec(  

                Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);  

         

        super.onMeasure(widthMeasureSpec, expandSpec); 

    } 

 



 

main.xml代码:

[html]

<p><?xml version="1.0" encoding="utf-8"?> 

<LinearLayout xmlns:android="<a href="http://schemas.android.com/apk/res/android">http://schemas.android.com/apk/res/android</a>" 

    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"</p><p>          /> 

      <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></p><p></LinearLayout></p> 

 

效果图如下:



    

  这里我的布局方式是上面一张图片,下面放置listView。

  对于此种布局方式,可以通过另外一种方式避免此问题。由于ListView有addHeadView()方法,那么我们可以直接将上面想加入的View通过  getLayoutInflater().inflate(this,R.layout.***) 加入到ListView的顶部即可。

 

  二、ScrollView中嵌套GridView的解决方案。

      ScrollView中嵌套GridView ,最简单的方法就是重写GridView方法,使其在绘制时重新计算GridView高度

     MyGridView.java代码如下:

[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 

    } 

    @Override 

    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 

        // TODO Auto-generated method stub 

        int expandSpec = MeasureSpec.makeMeasureSpec(  

                Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);  

        super.onMeasure(widthMeasureSpec, expandSpec);  

 

    } 



main.xml代码如下:

[java] 

<?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数据绑定。简单贴下代码:

[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; 

    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; 

        } 

        @Override 

        public int getCount() { 

            // TODO Auto-generated method stub 

            return texts.length; 

        } 

 

        @Override 

        public Object getItem(int position) { 

            // TODO Auto-generated method stub 

            return null; 

        } 

 

        @Override 

        public long getItemId(int position) { 

            // TODO Auto-generated method stub 

            return 0; 

        } 

 

        @Override 

        public View getView(int position, View convertView, ViewGroup parent) { 

            // TODO Auto-generated method stub 

            ViewHolder 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。

   效果图如下:

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: