天天看點

listview的一些屬性

1.listview 去除分割線: 法一:設定android:divider:="@null"  法二:android:divider="#00000000" #00000000後面兩個零表示透明 法三代碼中:.setDividerHeight(0) 高度設為0 2.改變背景cacheColorHint屬性: 改變背景背很簡單隻需要準備一張圖檔然後指定屬性android:background="@drawable/bg",如果你隻是換背景的顔色的話,可以直接指定android:cacheColorHint為你所要的顔色,如果你是用圖檔做背景的話,那也隻要将android: cacheColorHint指定為透明(#00000000) 就可以了 3.fadingEdge屬性: 上邊和下邊有黑色的陰影 android:fadingEdge="none"設定後沒有陰影了 4.scrollbars屬性 作用是隐藏l istView的滾動條,android:scrollbars="none" android:footerDividersEnabled//當設為false時,ListView将不會在各個footer之間繪制divider.預設為true。   5.listSelector屬性 設定清單項選中或點選後的顔色,可以設定android:listSelector=“@null”,選中或點選清單項時無背景顔色變化。 6..fastScrollEnabled屬性: 很多開發者不知道ListView清單控件的快速滾動滑塊是如何啟用的,Android開發網告訴大家,輔助滾動滑塊隻需要一行代 listview 點選後的背景: 1)設定listSelector   2)在布局檔案中設定item的background   3)在adapter的getview中設定 3)在adapter的getView方法中設定 if (convertView == null ) { convertView = LayoutInflater.from(context).inflate(R.layout.listitem, null ); } convertView.setBackgroundResource(R.drawable.selector);

ListView擷取高度,然後設定高度,解決嵌套不顯示問題

public static void setListViewHeightBasedOnChildren(ListView listView) 
{
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); 
listItem.measure( MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)); 
totalHeight += listItem.getMeasuredHeight(); 
}
ViewGroup.LayoutParams params = listView.getLayoutParams(); 
params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
listView.setLayoutParams(params);
}
           

使用這個代碼來擷取listview的高度,需要注意一下幾個問題:

1、listview的item的根布局一定要是LinearLayout; 因為其他的Layout(如RelativeLayout)沒有重寫onMeasure(),是以會在onMeasure()時抛出異常。

2、調用這個方法需要在擴充卡資料加載更新之後;

代碼如下: 

mAdapter.notifyDataSetChanged(); 

Function.getTotalHeightofListView(mListView);

3、擷取item的高度也可以用注釋掉的代碼,效果一樣的

法二、 自定義ListView,重載onMeasure()方法,設定全部顯示

public class ExpandListView extends ListView {
	public ExpandListView(Context context) {
		super(context);
	}
	
	public ExpandListView(Context context, AttributeSet attrs) {
		super(context, attrs);
	}
	public ExpandListView(Context context, AttributeSet attrs, int defStyle){
		super(context, attrs, defStyle);
	}

	@Override
	public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
		super.onMeasure(widthMeasureSpec, expandSpec);
	}
}
           

對listview中每個item高度的設定

ListView.LayoutParams params = new ListView.LayoutParams(ListView.LayoutParams.MATCH_PARENT,70);//設定寬度和高度  
convertView.setLayoutParams(params); 
           

Android關于ListView中item與控件搶奪焦點的那些事

Button控件搶奪了item的焦點事件,使得item不能觸發相應的點選事件,那麼,如果我們既想點選觸發Button的點選事件,又想點選觸發item的點選事件,我們應該怎麼做呢?

這裡有三種解決方案

1.将ListView中的Item布局中的子控件focusable屬性設定為false

2.在getView方法中設定button.setFocusable(false)

3.設定item的根布局的屬性Android:descendantFocusability="blocksDescendant"

我們可以發現,其實這三種方法都是為了讓Button等控件不能擷取焦點,進而使得item可以響應點選事件。

第三種方法使用起來相對友善,因為它是将item布局中的其他所有控件都設定為不能擷取焦點。

android:descendantFocusability屬性共有三個取值,分别為

beforeDescendants:viewgroup會優先其子類控件而擷取到焦點

afterDescendants:viewgroup 隻有當其子類控件不需要擷取焦點時才擷取焦點

blocksDescendants:viewgroup 會覆寫子類控件而直接獲得焦點

ListView監聽:

ListView的主要有兩種滑動事件監聽方法,OnTouchListener和OnScrollListener

1.OnTouchListener

OnTouchListener方法來自View中的監聽事件,可以在監聽三個Action事件發生時通過MotionEvent的getX()方法或getY()方法擷取到目前觸摸的坐标值,來對使用者的滑動方向進行判斷,并可在不同的Action狀态中做出相應的處理

mListView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()) {
                    case MotionEvent.ACTION_DOWN:
                        // 觸摸按下時的操作

                        break;
                    case MotionEvent.ACTION_MOVE:
                        // 觸摸移動時的操作

                        break;
                    case MotionEvent.ACTION_UP:
                        // 觸摸擡起時的操作

                        break;
                }
                return false;
            }
        });           
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

不僅僅隻有上面的三種Action狀态,MotionEvent類中還定義了很多其它狀态,我們可以靈活的使用這些狀态

  • MotionEvent.ACTION_DOWN:開始觸摸
  • MotionEvent.ACTION_MOVE:觸摸移動
  • MotionEvent.ACTION_UP:觸摸擡起
  • MotionEvent.ACTION_OUTSIDE:觸摸範圍超過了UI邊界
  • MotionEvent.ACTION_CANCEL:觸摸被取消時(詳見:http://stackoverflow.com/questions/11960861/what-causes-a-motionevent-action-cancel-in-android)
  • MotionEvent.ACTION_POINTER_DOWN:當有另外一個觸摸按下時(多點觸摸)
  • MotionEvent.ACTION_POINTER_UP:當另一個觸摸擡起時(多點觸摸)

2.OnScrollListener

OnScrollListener來自AbsListView中的監聽事件,因為ListView直接繼承自AbsListView,是以在AbsListView中有很多ListView相關資訊 

OnScrollListener中有兩個回調方法

  • public void onScrollStateChanged(AbsListView view, int scrollState):監聽滑動狀态的改變
  • public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount):監聽滑動

在源碼中有其詳細的解釋

/**
     * Interface definition for a callback to be invoked when the list or grid
     * has been scrolled.
     */
    public interface OnScrollListener {

        /**
         * The view is not scrolling. Note navigating the list using the trackball counts as
         * being in the idle state since these transitions are not animated.
         */
        public static int SCROLL_STATE_IDLE = ;

        /**
         * The user is scrolling using touch, and their finger is still on the screen
         */
        public static int SCROLL_STATE_TOUCH_SCROLL = ;

        /**
         * The user had previously been scrolling using touch and had performed a fling. The
         * animation is now coasting to a stop
         */
        public static int SCROLL_STATE_FLING = ;

        /**
         * Callback method to be invoked while the list view or grid view is being scrolled. If the
         * view is being scrolled, this method will be called before the next frame of the scroll is
         * rendered. In particular, it will be called before any calls to
         * {@link Adapter#getView(int, View, ViewGroup)}.
         *
         * @param view The view whose scroll state is being reported
         *
         * @param scrollState The current scroll state. One of
         * {@link #SCROLL_STATE_TOUCH_SCROLL} or {@link #SCROLL_STATE_IDLE}.
         */
        public void onScrollStateChanged(AbsListView view, int scrollState);

        /**
         * Callback method to be invoked when the list or grid has been scrolled. This will be
         * called after the scroll has completed
         * @param view The view whose scroll state is being reported
         * @param firstVisibleItem the index of the first visible cell (ignore if
         *        visibleItemCount == 0)
         * @param visibleItemCount the number of visible cells
         * @param totalItemCount the number of items in the list adaptor
         */
        public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
                int totalItemCount);
    }           
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48

2.1 OnScrollSateChanged方法

OnScrollSateChanged根據scrollState來決定其回調的次數,它有三種模式:

  • OnScrollListener.SCROLL_STATE_IDLE:滾動停止時的狀态
  • OnScrollListener.SCROLL_STATE_STOUCH_SCROLL:觸摸正在滾動,手指還沒離開界面時的狀态
  • OnScrollListener.SCROLL_STATE_FLING:使用者在用力滑動後,ListView由于慣性将繼續滑動時的狀态

當使用者沒有用力滑動時,OnScrollSateChanged方法隻會回調2次,否則回調三次,我們在使用時通常會以設定Flag标志,來區分不同的滑動狀态,進而進行相應的處理

2.2 OnScroll方法

在ListView滾動時會一直被回調,它通過裡面有三個參數來顯示目前ListView的滾動狀态

  • firstVisibleItem:目前能看見的第一個item的ID(從0開始)
  • visibleItemCount:目前可見的item總數
  • totalItemCount:清單中擴充卡總數量,也就是整個ListView中item總數

注意:目前可見的item總數,包括螢幕中沒有顯示完整的item,如顯示一半的item也會算在可見範圍内

通過這三個參數,我麼可以實作很多事件判斷,如: 

(1)判斷目前是否滑動到最後一行 

目前視圖中第一個item的ID加上目前螢幕中可見item的總數如果等于ListView中所有item總數時,就表示移動到了最後一行

if (firstVisibleItem + visibleItemCount == totalItemCount && totalItemCount > ) {
                    // 滾動到最後一行了              //滾動到最後一行,在這裡可以處理ListView上拉加載更多 
              }           
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

(2)判斷滑動的方向 

通過oldVisibleItem 記錄上一次firstVisibleItem的位置,再與滑動後的firstVisibleItem進行比較,就可得知滑動的方向

if (firstVisibleItem > oldVisibleItem) {
                    // 向上滑動
                }
                if (firstVisibleItem < oldVisibleItem) {
                    // 向下滑動
                }
                oldVisibleItem = firstVisibleItem;           
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
listview的一些屬性
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

ListView也為我們提供了一些封裝好了的方法,來擷取item的位置資訊

// 擷取目前可見區域内第一個item的id
        mListView.getFirstVisiblePosition();

        // 擷取目前可見區域内最後一個item的id
        mListView.getLastVisiblePosition();
           

ScrollView嵌套ListView預設位置不是最頂部的解決方案

描述:

Scrollview裡面嵌套了一個listview ,這是開發中最尋常的一種布局,遇到的問題是:在這個Scrollview頁面預設的起始位置不是最頂部,而是listview的底部。

原因:

  1. 在Activity計算視窗的高度時,是在listview沒有填充資料時候就完成的,由于ScrollView嵌套listview時沒有指定高度,是以ScrollView就會按照layout中定義的預設高度計算。
  2. 因為listview擷取了焦點。

解決:

  1. myScrollView.smoothScrollTo(0,20);
    需在listview資料加載完成後調用
  2. 在代碼裡去掉listview的焦點
    lv.setFocusable(false);
  3. Listview外套一層LinearLayout
  4. 跟EditText一樣,在父元素的屬性下面下下面這兩行即可

    Android:focusableInTouchMode=”true” 

    android:focusable=”true”

  5. 最開始的時候讓最上面其中一個控件獲得焦點,滾動條自然就到頂部去了,如下:

    txtBaseMsg.setFocusable(true); 

    txtBaseMsg.setFocusableInTouchMode(true); 

    txtBaseMsg.requestFocus();

轉載:四種方案解決ScrollView嵌套ListView問題

一、 為什麼要使用ScrollView嵌套ListView的奇怪的結構        

ScrollView和ListView都是滾動結構,按理說,這兩個控件在UI上的功能是一樣的,但是看看下面這個設計:       

listview的一些屬性

    這是天貓商城的确認訂單的頁面,ScrollView中嵌套了ExpandableListView,ExpandableListView上面有固定的一些控件,下面也有固定的一些控件,整體又要能夠滾動。     清單資料要嵌在固定資料中間,并且作為整體一起滾動,有了這樣的設計需求,于是就有了ScrollView嵌套ListView的奇怪結構。

二、 ScrollView、ListView嵌套結構碰到的問題    

不多說,直接看失敗例子:    

  1.     <ScrollView
  2.     android:id="@+id/act_solution_1_sv"
  3.     android:layout_width="fill_parent"
  4.     android:layout_height="fill_parent">
  5.     <LinearLayout 
  6.         android:layout_width="fill_parent"
  7.         android:layout_height="wrap_content"
  8.         android:orientation="vertical">
  9.         <TextView
  10.             android:layout_width="fill_parent"
  11.             android:layout_height="wrap_content"
  12.             android:text="\nListView上方資料\n" />
  13.         <ListView 
  14.             android:id="@+id/act_solution_1_lv"
  15.             android:layout_width="fill_parent"
  16.             android:layout_height="wrap_content">
  17.         </ListView>
  18.         <TextView
  19.             android:layout_width="fill_parent"
  20.             android:layout_height="wrap_content"
  21.             android:text="\nListView下方資料\n" />
  22.     </LinearLayout>
  23.     </ScrollView>

複制代碼

    ScrollView中隻能放一個控件,一般都放LinearLayout,orientation屬性值為vertical。在LinearLayout中放需要呈現的内容。ListView也在其中,ListView的高度設為适應自身内容(wrap_content)。粗略一看,應該沒有什麼問題。但是看下面的實際效果圖:           

listview的一些屬性

    圖中黑框的部分就是ListView,裡面放了20條資料,但是卻隻顯示了1條。

    控件的屬性設定上沒有問題,但是為什麼沒有按照我的想法走呢?

    看看下面這個圖:

listview的一些屬性

     是否有點明白了呢?原因就是scroll事件的消費處理以及ListView控件的高度設定問題。

    雖然我看源碼也看了不少,但是要說出來卻不知到該怎麼下手,我是大概知道原因,但是不知道怎麼整理完全。求高手賜教…

三、問題解決方案

1、手動設定ListView高度

    經過測試發現,在xml中直接指定ListView的高度,是可以解決這個問題的,但是ListView中的資料是可變的,實際高度還需要實際測量。于是手動代碼設定ListView高度的方法就誕生了。

  1. public static void setListViewHeightBasedOnChildren(ListView listView) { 
  2.     if(listView == null) return;
  3.     ListAdapter listAdapter = listView.getAdapter(); 
  4.     if (listAdapter == null) { 
  5.         // pre-condition 
  6.         return; 
  7.     } 
  8.     int totalHeight = 0; 
  9.     for (int i = 0; i < listAdapter.getCount(); i++) { 
  10.         View listItem = listAdapter.getView(i, null, listView); 
  11.         listItem.measure(0, 0); 
  12.         totalHeight += listItem.getMeasuredHeight(); 
  13.     } 
  14.     ViewGroup.LayoutParams params = listView.getLayoutParams(); 
  15.     params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1)); 
  16.     listView.setLayoutParams(params); 
  17. }

複制代碼     上面這個方法就是設定ListView的高度了,在為ListView設定了Adapter之後使用,就可以解決問題了。

    但是這個方法有個兩個細節需要注意:

        一是Adapter中getView方法傳回的View的必須由LinearLayout組成,因為隻有LinearLayout才有measure()方法,如果使用其他的布局如RelativeLayout,在調用listItem.measure(0, 0);時就會抛異常,因為除LinearLayout外的其他布局的這個方法就是直接抛異常的,沒理由…。我最初使用的就是這個方法,但是因為子控件的頂層布局是RelativeLayout,是以一直報錯,不得不放棄這個方法。

        二是需要手動把ScrollView滾動至最頂端,因為使用這個方法的話,預設在ScrollView頂端的項是ListView,具體原因不了解,求大神解答…可以在Activity中設定:

  1. sv = (ScrollView) findViewById(R.id.act_solution_1_sv);

複制代碼

2、使用單個ListView取代ScrollView中所有内容

    這個方法是我在試了幾個方法都失敗的情況下自己琢磨出來的。

    用一張圖來解釋這個方法的思想:

listview的一些屬性

    就是說,把整個需要放在ScrollView中的内容,統統放在ListView中,原ListView上方的資料和下方資料,都作為現ListView的一個itemView,和原ListView中的單條資料是平級的關系。

    xml布局方面十分簡單:

  1. <ListView 
  2.     android:id="@+id/act_solution_2_lv"
  3.     android:layout_width="fill_parent"
  4.     android:layout_height="wrap_content">
  5. </ListView>

複制代碼    一個單獨的ListView就可以了。

    原ListView上方資料和下方資料,都寫進兩個xml布局檔案中:

listview的一些屬性

    Java代碼方面,需要自定義一個Adapter,在Adapter中的getView方法中進行position值的判斷,根據position值來決定inflate哪個布局:

  1. public View getView(int position, View convertView, ViewGroup parent) {
  2.             //清單第一項
  3.     if(position == 0){
  4.        convertView = inflater.inflate(R.layout.item_solution2_top, null);
  5.         return convertView;
  6.     }
  7.             //清單最後一項
  8.     else if(position == 21){
  9.         convertView = inflater.inflate(R.layout.item_solution2_bottom, null);
  10.         return convertView;
  11.     }
  12.             //普通清單項
  13.     ViewHolder h = null;
  14.     if(convertView == null || convertView.getTag() == null){
  15.         convertView = inflater.inflate(R.layout.item_listview_data, null);
  16.         h = new ViewHolder();
  17.         h.tv = (TextView) convertView.findViewById(R.id.item_listview_data_tv);
  18.         convertView.setTag(h);
  19.     }else{
  20.         h = (ViewHolder) convertView.getTag();
  21.     }
  22.     h.tv.setText("第"+ position + "條資料");
  23.     return convertView;
  24. }

複制代碼     在Activty中,隻需要直接為ListView設定自定義的Adapter就行了。

  1. lv = (ListView) findViewById(R.id.act_solution_2_lv);
  2. adapter = new AdapterForListView2(this);
  3. lv.setAdapter(adapter);

複制代碼

3、使用LinearLayout取代ListView

    既然ListView不能适應ScrollView,那就換一個可以适應ScrollView的控件,幹嘛非要吊死在ListView這一棵樹上呢?而LinearLayout是最好的選擇。但如果我仍想繼續使用已經定義好的Adater呢?我們隻需要自定義一個類繼承自LinearLayout,為其加上對BaseAdapter的适配。

  1. import android.content.Context;
  2. import android.util.AttributeSet;
  3. import android.util.Log;
  4. import android.view.View;
  5. import android.widget.BaseAdapter;
  6. import android.widget.LinearLayout;
  7. public class LinearLayoutForListView extends LinearLayout {
  8.     private BaseAdapter adapter;
  9.     private OnClickListener onClickListener = null;
  10.     public void bindLinearLayout() {
  11.         int count = adapter.getCount();
  12.         this.removeAllViews();
  13.         for (int i = 0; i < count; i++) {
  14.             View v = adapter.getView(i, null, null);
  15.             v.setOnClickListener(this.onClickListener);
  16.             addView(v, i);
  17.         }
  18.        Log.v("countTAG", "" + count);
  19.     }
  20.     public LinearLayoutForListView(Context context) {
  21.         super(context);

複制代碼     上面的代碼拷貝儲存為LinearLayoutForListView.class,或者直接拷貝Demo中的這個類在自己的工程裡。我們隻需要把原來xml布局檔案中的ListView替換為這個類就行了:

  1. <pm.nestificationbetweenscrollviewandabslistview.mywidgets.LinearLayoutForListView
  2.     android:id="@+id/act_solution_3_mylinearlayout"
  3.     android:layout_width="fill_parent"
  4.     android:layout_height="wrap_content"
  5.     android:orientation="vertical" >
  6. </pm.nestificationbetweenscrollviewandabslistview.mywidgets.LinearLayoutForListView>

複制代碼     在Activity中也把ListView改成LinearLayoutForListView,就能成功運作了。

  1. mylinearlayout = (LinearLayoutForListView) findViewById(R.id.act_solution_3_mylinearlayout);
  2. adapter = new AdapterForListView(this);
  3. mylinearlayout.setAdapter(adapter);

複制代碼

4、自定義可适應ScrollView的ListView

    這個方法和上面的方法是異曲同工,方法3是自定義了LinearLayout以取代ListView的功能,但如果我脾氣就是倔,就是要用ListView怎麼辦?那就隻好自定義一個類繼承自ListView,通過重寫其onMeasure方法,達到對ScrollView适配的效果。

    下面是繼承了ListView的自定義類:

  1. import android.content.Context;
  2. import android.util.AttributeSet;
  3. import android.widget.ListView;
  4. public class ListViewForScrollView extends ListView {
  5.     public ListViewForScrollView(Context context) {
  6.         super(context);
  7.     }
  8.     public ListViewForScrollView(Context context, AttributeSet attrs) {
  9.         super(context, attrs);
  10.     }
  11.     public ListViewForScrollView(Context context, AttributeSet attrs,
  12.         int defStyle) {
  13.         super(context, attrs, defStyle);
  14.     }
  15.     @Override
  16.     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
  17.         int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
  18.         MeasureSpec.AT_MOST);
  19.         super.onMeasure(widthMeasureSpec, expandSpec);
  20.     }
  21. }

複制代碼     三個構造方法完全不用動,隻要重寫onMeasure方法,需要改動的地方比起方法3少了不是一點半點…

    在xml布局中和Activty中使用的ListView改成這個自定義ListView就行了。代碼就省了吧…

    這個方法和方法1有一個同樣的毛病,就是預設顯示的首項是ListView,需要手動把ScrollView滾動至最頂端。

  1. sv = (ScrollView) findViewById(R.id.act_solution_4_sv);
  2. sv.smoothScrollTo(0, 0);

複制代碼

5、設定ScrollView的屬性,使ListView能夠成功嵌套(無法達到預定效果)

    這個方法是我在寫Demo的時候找到的,第一反應是有這個方法我還寫這個Demo幹嘛,隻要在布局檔案中添加一個屬性就搞定了。不過結果确實是ListView的大小把ScrollView的剩餘部分填滿了,但卻不能滾動,真是個緻命的問題…

    不廢話了,布局檔案中:

  1. <ScrollView
  2.     android:id="@+id/act_solution_5_sv"
  3.     android:layout_width="fill_parent"
  4.     android:layout_height="fill_parent"
  5.     android:layout_below="@+id/act_solution_5_vg_top"
  6.     android:fillViewport="true">

複制代碼     設定fillViewport的屬性為true即可。簡單吧?

    但是不能滾動這個緻命的問題我卻不知道該怎麼解決了,繼續求大神解答…

四、幾種種方法的優缺點比較     上面一共給出了4中親測可用的方法,各自有使用條件,複雜程度也各不相同。

    下面我來從幾個方面來分析幾種方法的優勢和劣勢。

    方法1的優點是不用對使用的控件做任何修改,隻需要使用一個現成的方法就好了,而最大的限制是ListView的item隻能由LinearLayout這一個布局組成,對于一些複雜的布局就不适用了。如果你的工程急需解決這個問題,而且滿足方法的使用條件,即ListView的item布局簡單,完全有LinearLayout組成,你就隻需要把setListViewHeightBasedOnChildren方法拿過去就行了。

    方法2的優點是布局檔案設計簡單、Activity中的代碼也很少,而缺點卻是自定義Adapter變得十分複雜,而且執行效率會變低,因為findViewById是十分費時的操作,而使用ViewHolder結構可以解決費時的問題(有興趣的童鞋可以去搜一艘ViewHolder結構),然而使用了方法2的話,會破壞這種結構。如果你的工程設計上偏簡單,ListView子項相對少、ListView上下方資料少、子項間互動少的話,可以嘗試一下。

    方法3的優點是完全解決了ScrollView嵌套ListView的問題,同時代碼較少,你甚至可以直接使用LinearLayout,而在Activity中手動為LinearLayout添加子項控件,不過需要注意的是,在添加前需要調用其removeAllViews的方法,否則可能會出現預想不到的事情,那時你會想念天國的ListView的。缺點不是很明顯,但還是有兩個:一是使用的不是系統控件,不能在xml布局的Graphical Layout視圖中直接看到效果;二是不能向ListView那樣可以使用ViewHolder結構,在加載大量子項時會費很多時間在findViewById中。如果你的清單資料比較少的話,不妨試試這個方法,除了不能使用ViewHolder結構,使用方法幾乎和ListView一樣。

    方法4…比方法3更簡單,代碼更少,同時保留了ListView原有的所有方法,包括notifyDataSetChanged方法,相比其他方法是最趨近于完美的方法,隻是需要在Activity中設定ScrollView滾動至頂端。如果你還在猶豫不決的話就選這個方法吧,我想我以後是隻會用這個方法了…

轉載Demo下載下傳位址:http://download.csdn.net/detail/lygscg123/7776719

繼續閱讀