天天看點

總結ScrollView中嵌套ListView/GridView的方法

一、scrollview中嵌套listview/gridview:

     方法一:計算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);

   totalheight += listitem.getmeasuredheight();

  viewgroup.layoutparams params = listview.getlayoutparams();

  params.height = totalheight

    + (listview.getdividerheight() * (listadapter.getcount() - 1));

  listview.setlayoutparams(params);

 }

     處理方式:在将樓上這個方法拷貝到工具類中,在listview.setadapter 的下方調用這個方法即可,如下所示:

appradapter = new approvedpersonadapter(mcontext, mlistaped);

mlistview.setadapter(appradapter);

listheightutils.setlistviewheightbasedonchildren(mlistview);

    方法二:重寫listview/gridview

    重寫listview:

public class myscrollvlistview extends listview {

 public myscrollvlistview(context context) {

  super(context);

  // todo auto-generated constructor stub

 public myscrollvlistview(context context, attributeset attrs) {

  super(context, attrs);

 public myscrollvlistview(context context, attributeset attrs, int defstyle) {

  super(context, attrs, defstyle);

 @override

 protected void onmeasure(int widthmeasurespec, int heightmeasurespec) {

  int expandspec = measurespec.makemeasurespec(integer.max_value >> 2,

    measurespec.at_most);

  super.onmeasure(widthmeasurespec, expandspec);

}

    重寫gridview:

public class myscrollgridview extends gridview {  

    private boolean havescrollbar = false;  

    public myscrollgridview(context context) {  

        super(context);  

    }  

    public myscrollgridview(context context, attributeset attrs) {  

        super(context, attrs);  

    public myscrollgridview(context context, attributeset attrs, int defstyle) {  

        super(context, attrs, defstyle);  

    /** 

     * 設定是否有scrollbar,當要在scollview中顯示時,應當設定為false。 預設為 true 

     *  

     * @param havescrollbars 

     */  

    public void sethavescrollbar(boolean havescrollbar) {  

        this.havescrollbar = havescrollbar;  

    @override  

    public void onmeasure(int widthmeasurespec, int heightmeasurespec) {  

        int expandspec = measurespec.makemeasurespec(integer.max_value >> 2,  

                measurespec.at_most);  

        super.onmeasure(widthmeasurespec, expandspec);  

    }

     處理方式:和正常的布局listview/gridview一樣,隻是這裡需要用全路徑,即可解決,如下所示:

<com.derek.views.myscrollvlistview

        android:id="@+id/mlistview"

        android:layout_width="match_parent"

        android:layout_height="wrap_content"

        >

    </com.derek.views.myscrollvlistview>

    方法三:linerlayout代替listview/gridview

    1、先在需要布局listview/gridview的地方布局上一個linerlayout,如下所示:

 <linearlayout

            android:id="@+id/mlinearlayout"

            android:layout_width="match_parent"

            android:layout_height="wrap_content"

            android:layout_gravity="center_vertical|center_horizontal"

            android:adjustviewbounds="true"

            android:background="#85808c"

            android:orientation="vertical" >

 </linearlayout>

      2、在findviewbyid該對象,如下所示:

mlinearlayout= (linearlayout) findviewbyid(r.id.mlinearlayout);

      3、初始化資料

/**

  * 動态添加資料

  * @param jsonarrayops

  */

 private void initgridview(jsonarray jsonarrayops) {

  mlinearlayout.removeallviews();

  arraylist<hashmap<string, object>> lstitem = getoptiondata();

  simpleadapter saimageadapter = new simpleadapter(mcontext,

    lstitem,// 資料源

                r.layout.item_gridview_button,// 顯示布局

                new string[] {"itemtext" },

                new int[] {  r.id.mbtnitemtext });

  mgridviewbutton = new squaregridview(mcontext);

  mgridviewbutton.setadapter(saimageadapter);

  int size = jsonarrayops.length();

  int numcolumns = 0;

  if (size%2 == 0) {

   numcolumns = 2;

  }else if(size%3 == 0){

   numcolumns = 3;

  }else{

  mgridviewbutton.setnumcolumns(numcolumns);

//  mgridviewbutton.setcolumnwidth(120);

  mgridviewbutton.setgravity(gravity.center);

  mgridviewbutton.setstretchmode(gridview.stretch_column_width);

  //去掉點選效果的背景

  mgridviewbutton.setselector(new colordrawable(color.transparent));

  mgridviewbutton.setverticalspacing(densitydiutil

    .dip2px(mcontext, 3));

  int heigth = (int) getresources().getdimension(r.dimen.height_26_80);

  if (size <= 2) {

   mgridviewbutton.setlayoutparams(new linearlayout.layoutparams(

     layoutparams.fill_parent, heigth/2));

  } else {

     layoutparams.fill_parent, heigth));

  /**監聽事件**/

  mgridviewbutton.setonitemclicklistener(new onitemclicklistener() {

   @override

   public void onitemclick(adapterview<?> parent, view view,

     int position, long id) {

    string data = edtcontent.gettext().tostring();

    //***指派的目的是為了點選拒絕時能促發背景修改資料**//*

    if (textutils.isempty(data)) {

     data = mcontext.getresources().getstring(r.string.strappapproval);

    }

    try {

     string mname = jsonarrayops.getstring(position);

     requestapprovaldata( mname,data);

     tools.printinfo(mname);

    } catch (jsonexception e) {

     e.printstacktrace();

   }

  });

//   new layoutparam(layoutparam.fill_parent, layoutparam.fill_parent)

  mlinearlayout.addview(mgridviewbutton);

    如此将資料組裝好後,該問題也基本解決了,mlinearlayout.removeallviews();

表示先清空所有的view,便于每次添加進去的都是新的view。此方法在很多動态添加資料中都會用上,listview的方法與此一樣。

二、scrollview嵌套listview時,嵌套的布局是a布局+listview+b布局的形式,當a布局中的内容超過一屏時,listview的最後一個item總是顯示不全?

  解決方案: (1)listview不能用自定義的,必須用原生的listview;

         (2)listview的寬高都用 match_parent或fill_parent;

         (3)用計算高度的方式去實作setlistviewheightbasedonchildren(listview);

         (4)adapter的item的根布局必須為linearlayout布局,不然計算高度時會有問題;

         (5)scrollview中添加屬性 android:fillviewport="true"

  利用以上的5點,基本可以解決問題,我是這樣解決,如果有沒有解決的,請注意布局上看看有什麼問題,把多餘的功能去掉,從最基本的隻顯示listview開始調節,一個功能一個功能的加上去,看看是哪裡出問題,就逐漸排除并解決。

     listview中嵌套listview的處理在後續的文章中單獨講解,其實這三種方法網上也基本有的,隻是便于android的學習記錄一下這個過程。