解決Android ListView 和 ScrollView 共存時沖突 問題 方法其一


轉載請注明出處:

http://www.goteny.com/articles/2013/11/8.html

http://www.cnblogs.com/zjjne/p/3428480.html

 

當同一個頁面布局中的ScrollView中包含有ListView時,兩個布局由於都有滑動而導致沖突,最明顯的特征就是當ListView中有多個子項時,會出現顯示不全的情況,只會顯示一兩個子項。

 

以前查到一個簡單的解決辦法setListViewHeightBasedOnChildren(ListView listView)的那個辦法,是測出ListView中每一個子項視圖的高度,然后再相加起來,以這個值來設定整個ListView的高度。這種方法的優點是比較簡單,能解決子項視圖布局比較簡單且文字較少的情況;但不足之處是每次刷新ListView時都要調用這個函數來重新設定ListView的高度,重點是:若子項視圖中文字過多,出現文字自動換行的時候,此時測出來的高度就不准確了,難以做到准確設置ListView的高度。

 

這次要介紹的方法雖說有點麻煩,但是相對來說比較治本的方法,其思想是繼承並擴展線性布局LinearLayout,用LinearLayout替代ListView來實現ListView的功能和效果。

 

下面是效果示例:

這是修改前的沖突情況(ListView顯示只能顯示第一行)

 

這是修改后的效果

 

 

本文的實現思想和代碼是在

Android 解決ListView ScrollView 共存沖突的問題http://terryblog.blog.51cto.com/1764499/373509

這篇文章的基礎上作了少許修改和“添加子項間分隔線、子項點擊事件監聽”而成的。

 

主要思想是:

給LinearLayout添加BaseAdapter、OnItemClickListener成員,

然后在綁定布局時調用BaseAdapter的getView方法取得子項的視圖View,

將此View用addView方法添加進LinearLayout中;

並設置每一個子項視圖View的監聽點擊事件OnClickListener,

在OnClickListener的onClick方法中調用OnItemClickListener的

onItemClick方法,即在將子項的點擊事件轉發到LinearLayout的onItemClick事件中。

 

下面是用來替代ListViewLinearLayout代碼,此LinearLayoutForListView作為自定義控件來替代ListView

用法和ListView的用法一樣,使用BaseAdapter來做適配器

  1 package com.and.mine;
  2 
  3 import android.content.Context;
  4 import android.util.AttributeSet;
  5 import android.util.Log;
  6 import android.util.TypedValue;
  7 import android.view.View;
  8 import android.widget.AdapterView.OnItemClickListener;
  9 import android.widget.BaseAdapter;
 10 import android.widget.LinearLayout;
 11 
 12 public class LinearLayoutForListView extends LinearLayout
 13 {
 14     private BaseAdapter adapter;
 15     private OnItemClickListener onItemClickListener;
 16 
 17     
 18     /**
 19      * 通過 Java代碼  實例化
 20      * @param context
 21      */
 22     public LinearLayoutForListView(Context context)
 23     {
 24         super(context);
 25         //設置LinearLayoutForListView為垂直布局,否者默認為水平布局,容易疏忽導致子項顯示不全
 26         LinearLayoutForListView.this.setOrientation(LinearLayout.VERTICAL);
 27     }
 28 
 29     
 30     /**
 31      * 此構造函數可以允許我們通過 XML的方式注冊 控件
 32      * @param context
 33      * @param attrs
 34      */
 35     public LinearLayoutForListView(Context context, AttributeSet attrs)
 36     {
 37         super(context, attrs);
 38         LinearLayoutForListView.this.setOrientation(LinearLayout.VERTICAL);
 39     }
 40     
 41     
 42 
 43     /**
 44      * 設置適配器
 45      * 
 46      * @param adpater
 47      */
 48     public void setAdapter(BaseAdapter adpater)
 49     {
 50         this.adapter = adpater;
 51         bindLinearLayout();
 52     }
 53 
 54     /**
 55      * 獲取適配器Adapter
 56      * 
 57      * @return adapter
 58      */
 59     public BaseAdapter getAdpater()
 60     {
 61         return adapter;
 62     }
 63 
 64     
 65     
 66     /**
 67      * 綁定布局:將每個子項的視圖view添加進此線性布局LinearLayout中
 68      */
 69     public void bindLinearLayout()
 70     {
 71         int count = adapter.getCount();
 72         for (int i = 0; i < count; i++)
 73         {
 74             View v = adapter.getView(i, null, null);
 75 
 76             if (i != count - 1)
 77             {    //添加每項item之間的分割線
 78                  v = addLine(v);
 79             }
 80             addView(v, i);
 81         }
 82         setItemClickListener();
 83         Log.v("countTAG", "" + count);
 84     }
 85 
 86     /**
 87      * 添加每項item之間的分割線
 88      * 
 89      * @param view
 90      * @return
 91      */
 92     public View addLine(View view)
 93     {
 94         //分割線view
 95         View lineView = new View(view.getContext());
 96 
 97         // 將數據從dip(即dp)轉換到px,第一參數為數據原單位(此為DIP),第二參數為要轉換的數據值
 98         float fPx = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
 99                 (float) 0.5, view.getResources().getDisplayMetrics());
100         int iPx = Math.round(fPx);
101 
102         LayoutParams layoutParams = new LayoutParams(
103                 LinearLayout.LayoutParams.MATCH_PARENT, iPx);
104         lineView.setLayoutParams(layoutParams);
105         lineView.setBackgroundColor(view.getSolidColor());
106 
107         LinearLayout ly = new LinearLayout(view.getContext());
108         ly.setOrientation(LinearLayout.VERTICAL);
109 
110         ly.addView(view);
111         ly.addView(lineView);
112 
113         return ly;
114     }
115 
116     
117     /**
118      * 設置點擊子項事件監聽對象
119      * @param onItemClickListener
120      */
121     public void setOnItemClickListener(OnItemClickListener onItemClickListener)
122     {
123         this.onItemClickListener = onItemClickListener;
124         setItemClickListener();
125     }
126     
127     /**
128      * 獲取點擊子項事件監聽對象
129      * @return
130      */
131     public OnItemClickListener getOnItemClickListener()
132     {
133         return onItemClickListener;
134     }
135     
136     
137     /**
138      * 設置子項點擊事件
139      */
140     private void setItemClickListener()
141     {
142         if (adapter != null)
143         {
144             for (int i = 0; i < LinearLayoutForListView.this.getChildCount(); i++)
145             {
146                 View view = LinearLayoutForListView.this.getChildAt(i);
147                 if (onItemClickListener != null)
148                 {
149                     //設置子項點擊事件
150                     view.setOnClickListener(new ItemClickListener(view, i, adapter.getItemId(i)));
151                 }
152             }
153         }
154     }
155     
156     class ItemClickListener implements OnClickListener
157     {
158         View view;
159         int position;
160         long id;
161         
162         public ItemClickListener(View view, int position, long id)
163         {
164             this.view = view;
165             this.position = position;
166             this.id = id;
167         }
168 
169         @Override
170         public void onClick(View v)
171         {
172             //將子項視圖的點擊事件轉發到整個listview的OnItemClick事件中
173             //此方法有局限性,第一個參數 AdapterView<?> parent(即當前listView的視圖)沒傳入onItemClick()中
174             onItemClickListener.onItemClick(null, view, position, id);
175         }
176     }
177 }

 

XML中使用自定義控件來調用LinearLayoutForListView

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical" >

    <com.and.mine.LinearLayoutForListView
        android:id="@+id/list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >
    </com.and.mine.LinearLayoutForListView>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="使用方法" />

</LinearLayout>


 

當然這種這種方法也是存在不足之處的,歡迎各位指正

 

轉載請注明出處:

http://www.goteny.com/articles/2013/11/8.html

http://www.cnblogs.com/zjjne/p/3428480.html

 

THE END


 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM