1. 程式人生 > >Android ScrollView與ListView,GridView共存衝突解決方案

Android ScrollView與ListView,GridView共存衝突解決方案

我們在真實專案中通常會遇到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。

   效果圖如下:

相關推薦

Android ScrollViewListView,GridView共存衝突解決方案

我們在真實專案中通常會遇到ListView或者GridView巢狀在ScrollView中問題。但是做的時候會發現,一旦兩者進行巢狀,即會發生衝突。得不到我們希望的效果。由於ListView和GridView本身都繼承於ScrollView,一旦在ScrollView中巢

ScrollViewviewpager滑動事件衝突,點選事情衝突解決方案

在產品適配的時候我加了ScrollView,但是產品提出了一個向上輪播需求 首先把豎直向上的viewpager粘出來: package com.cfiigroup.zhehui.hepaidai.view; import android.view.MotionEvent; impo

Android ScrollViewViewPager滑動上下左右衝突

重寫ScrollView public class CustomScrollView extends ScrollView {     private GestureDetector mGestureDetector;     View.OnTouchListener m

【安卓】android第三方庫導致support版本衝突解決方案

問題 升級compileSdk版本到26,同時修改了support包的版本,報錯 all com.android.support libraries must use the exact same version specification(mixin

Android Studio-SVN程式碼下載,提交,衝突解決方案

注:可選擇安裝中文包 1.2> 桌面右擊出現svn選項說明安裝成功 2 配置Android Studio SVN 2.1>選擇File 2.2>選擇Setting 2.3>選擇Version Control是–

android ListView/GridViewScrollView巢狀的滑動衝突解決

首先說一下思路,主要就是去掉子ListView/GridView的內容全部顯示出來,使其不需要滑動。然後用ScrollView將其包裹在其中,接管滑動事件,達到整個佈局的滑動效果。 實際做法需要將ListView/GridView 與 ScrollView 覆

ScrollView ListView 以及 GridView 滑動衝突完美解決

  我們在用ScrollView巢狀ListView或者GridView的時候會遇到兩個問題,一個問題是ListView高度不正常,另外一個問題是ListView無法滑動。因為這幾個控制元件太常用了。我們來看看應該怎麼解決呢?在解決這個問題之前,我們先來解決一個

ScrollViewListView(ExpandableListView)的滑動衝突解決方法

在Android開發中,如果外層使用ScrollView巢狀ListView(ExpandableListView),以下統一稱為ListView,會導致ListView的顯示高度變窄,甚至不能實現螢幕外內容的括展,那麼滑動衝突就出現了。 解決思路: 思路一: 在XML中將高度固定

AndroidListViewButton的共存問題解決

這兩天在搗鼓ListView widget,為了在ListView中加入Button這類的有 “點選” 事件的widget,請教了不少高手,感謝LandMark對我的認真講解,下面把解決過程描述一下。 ListView 和 其它能觸發點選事件的widget無法一起正常工作的

解決ScrollViewListView衝突的方法

import android.view.View; import android.view.ViewGroup; import android.widget.ListAdapter; import android.widget.ListView; public class ListViewUnScoll {

淺談android中的ListView解決ScrollViewListView巢狀衝突(實際上一切都是浮雲,閒的蛋疼)(一)

     相信大家都已經可以熟練使用ListView和GridView,大神們估計都在使用RecyclerView了。如果還在使用ListView,你肯定有這樣的一個深刻的感受,那就是在做一個APP的時候使用ListView和GridView很頻繁,並且經常會遇到一個頁面中

android tv跑馬燈效果HorizontalScrollView焦點衝突解決方案

我整個移動的view是繼承了HorizontalScrollView,但是發現我遙控器向右移動的時候,view沒焦點了,我view裡面有一個跑馬燈效果,就是在有焦點的時候才出現跑馬燈,沒焦點的時候隱藏

AndroidListView、RecyclerView、ScrollView裡巢狀ListView 相對優雅的解決方案:NestFullListView

一 背景概述: ScrollView裡巢狀ListView,一直是Android開發者(反正至少是我們組)最討厭的設計之一,完美打破ListView(RecyclerView)的複用機制,成功的將Native頁面變成一個又臭又長的H5網頁效果,但由於這種設計需

android-Ultra-Pull-To-Refresh重新整理框架viewpager滑動衝突解決方案

文章概述: 問題描述: liaohuqiu 開源的 android-Ultra-Pull-To-Refresh 下拉重新整理框架,在使用時,會經常遇到巢狀banner的使用場景,即:子ViewGroup巢狀ViewPager使用,例如: <c

android下拉重新整理和listview衝突解決方案

相關文章: 常見的下拉重新整理都是帶有一些自定義的listview、gridview和webview,我們導包直接用就行了,但是為什麼他們要自定義一些常用的控制元件呢?直接在外邊套用不行嗎?類

ScrollViewListView合用(TextView多行顯示時計算不正確)的問題解決

最近測試的時候發現在使用SrollView 中使用兩個listView,如果使用特大字型的話,比較長的LISTVIEW多行顯示會有問題。在網上搜索了一下,大概有兩種解決方案,一種是重寫ListView的onMeasure方法,一種是重寫TextView的onMeasure方

完美解決HorizontalScrollViewListView滑動事件衝突

HorizontalScrollView與ListView滑動事件衝突,導致ListView下拉不靈敏。下面給出一種比較完美的實現方式,如果是縱向的ScrollView,對應改一下就好了~~上程式碼pa

Android RecyclerViewListView比較

gets 功能 itemid nested dem 集合 title fyi 這一 RecyclerView 概述 RecyclerView 集成自 ViewGroup 。RecyclerView是Android-support-V7版本中新增的一個Widgets,官方對

ScrollView下,ListView重複呼叫getview解決方案

首先講一下我遇到的需求吧,頁面是這樣的,上邊有東西,中間是列表,下邊還有東西。首先我看到列表立刻就想到了用ListView,但是頁面有限,只能用ScrollView包一下。想到就做唄。我就在ScrollView裡面加了一個ListView, ListView設定的是wapcontent,這樣就出現

unity3dScrollRectOnDrag事件的衝突解決方法

借鑑  https://www.jianshu.com/p/8bfe94822886 using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI; /// <summary> /// 指令碼掛載到每個可拖拽