Android 解决ListView 和 ScrollView 共存冲突的问题

it2022-05-09  26

ListView 与 ScrollView 同在一个界面用头脑想想都觉得不大可能这样做,但还真的有美工这样做了,有点郁闷~!!沟通无果,解决之~~~~!初期还真没啥头绪,Google 一下看到有很多同样碰到这类头痛的问题,不好意思还没描述问题症状。ListView 与 ScrollView 同在一界面会导致ListView 显示变形,因为ListView 也有自带的滚动事件,故无法与ScrollView 相容,可能造成的现象是ListView 只能显示一行或者两行,其他数据在那一点儿宽的地方做滚动,甚不雅观。

下面是我的一个实现 步骤:

1、继承LinearLayout,既然会冲突那就不用ListView 改成线性布局做动态布局效果2、继承BaseAdapter ,可以参照一下Android app源码中 Widget 目录下的SimpleAdapter 为前面扩展的LinearLayout做数据。3、模拟数据填充扩展后的BaseAdapter 为扩展后的LinearLayout 加载数据

第一步:新建LinearLayoutForListView 类使其扩展LinearLayout重写以下两个方法:

 

public  LinearLayoutForListView(Context context) {         super (context);    }     public  LinearLayoutForListView(Context context, AttributeSet attrs) {         super (context, attrs);         //  TODO Auto-generated constructor stub     }

 

这两个方法可选,不过建议都写上,第一个方法可以让我们通过 编程的方式 实例化出来,第二个方法可以允许我们通过 XML的方式注册 控件,可以在第二个方法里面为扩展的复合组件加属性,详细使用方法请点击这里 。

为其添加get / set 方法

/**      * 获取Adapter     *      *  @return  adapter      */      public  AdapterForLinearLayout getAdpater() {         return  adapter;    }     /**      * 设置数据     *      *  @param  adpater      */      public   void  setAdapter(AdapterForLinearLayout adpater) {         this .adapter  =  adpater;        bindLinearLayout();    }     /**      * 获取点击事件     *      *  @return       */      public  OnClickListener getOnclickListner() {         return  onClickListener;    }     /**      * 设置点击事件     *      *  @param  onClickListener      */      public   void  setOnclickLinstener(OnClickListener onClickListener) {         this .onClickListener  =  onClickListener;    }

 

第二步:新建AdapterForLinearLayout 类继承自BaseAdapter,并为其添加构造函数

 

private  LayoutInflater mInflater;     private   int  resource;     private  List <?   extends  Map < String,  ?>>  data;     private  String[] from;     private   int [] to;     public  AdapterForLinearLayout(Context context,            List <?   extends  Map < String,  ?>>  data,  int  resouce, String[] from,             int [] to) {         this .data  =  data;         this .resource  =  resouce;         this .data  =  data;         this .from  =  from;         this .to  =  to;         this .mInflater  =  (LayoutInflater) context                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);    }

 

此构造函数模仿 simpleAdapter 通过传进来的resouce 为布局设置数据。通过继承BaseAdapter 重要的实现方法在下面getView ,此方法判断通过传进来的 String[] from 与 int[] to 为分别查找出View 并为View 设置相应的Text,代码如下:

 

@Override     public  View getView( int  position, View convertView, ViewGroup parent) {         //  TODO Auto-generated method stub         convertView  =  mInflater.inflate(resource,  null );        Map < String,  ?>  item  =  data.get(position);         int  count  =  to.length;         for  ( int  i  =   0 ; i  <  count; i ++ ) {            View v  =  convertView.findViewById(to[i]);            bindView(v, item, from[i]);        }        convertView.setTag(position);         return  convertView;    }     /**      * 绑定视图     *  @param  view     *  @param  item     *  @param  from      */      private   void  bindView(View view, Map < String,  ?>  item, String from) {        Object data  =  item.get(from);         if  (view  instanceof  TextView) {            ((TextView) view).setText(data  ==   null   ?   ""  : data.toString());        }    }

 

Tip:

BindView 方法是一个自定义方法,在方法体内可以为通过判断使本类更具灵活性,如上,你不仅可以判断是TextView 并且可以传入任何你想要的View 只要在方法体内加入相应判断即可,数据可以通过data 做相应处理,具体如何操作读者可另行测试。convertView.setTag(position); 此句代码为View 设置tag 在以后我们可以通过 getTag 找出下标,后文有介绍如何通过下标操作数据。

下面是两个类的全部代码,读者可以无须更改直接使用:

LinearLayoutForListView

package  com.terry.widget; import  android.content.Context; import  android.util.AttributeSet; import  android.util.Log; import  android.view.View; import  android.widget.LinearLayout; public   class  LinearLayoutForListView  extends  LinearLayout {     private  AdapterForLinearLayout adapter;     private  OnClickListener onClickListener  =   null ;     /**      * 绑定布局      */      public   void  bindLinearLayout() {         int  count  =  adapter.getCount();         for  ( int  i  =   0 ; i  <  count; i ++ ) {            View v  =  adapter.getView(i,  null null );            v.setOnClickListener( this .onClickListener);             if  (i  ==  count  -   1 ) {                LinearLayout ly  =  (LinearLayout) v;                ly.removeViewAt( 2 );            }            addView(v, i);        }        Log.v( " countTAG " ""   +  count);    }     public  LinearLayoutForListView(Context context) {         super (context);    }     public  LinearLayoutForListView(Context context, AttributeSet attrs) {         super (context, attrs);         //  TODO Auto-generated constructor stub     }     /**      * 获取Adapter     *      *  @return  adapter      */      public  AdapterForLinearLayout getAdpater() {         return  adapter;    }     /**      * 设置数据     *      *  @param  adpater      */      public   void  setAdapter(AdapterForLinearLayout adpater) {         this .adapter  =  adpater;        bindLinearLayout();    }     /**      * 获取点击事件     *      *  @return       */      public  OnClickListener getOnclickListner() {         return  onClickListener;    }     /**      * 设置点击事件     *      *  @param  onClickListener      */      public   void  setOnclickLinstener(OnClickListener onClickListener) {         this .onClickListener  =  onClickListener;    }}

 

 

 

AdapterForLinearLayout

package  com.terry.widget; import  java.util.List; import  java.util.Map; import  android.content.Context; import  android.view.LayoutInflater; import  android.view.View; import  android.view.ViewGroup; import  android.widget.BaseAdapter; import  android.widget.TextView; public   class  AdapterForLinearLayout  extends  BaseAdapter {     private  LayoutInflater mInflater;     private   int  resource;     private  List <?   extends  Map < String,  ?>>  data;     private  String[] from;     private   int [] to;     public  AdapterForLinearLayout(Context context,            List <?   extends  Map < String,  ?>>  data,  int  resouce, String[] from,             int [] to) {         this .data  =  data;         this .resource  =  resouce;         this .data  =  data;         this .from  =  from;         this .to  =  to;         this .mInflater  =  (LayoutInflater) context                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);    }    @Override     public   int  getCount() {         //  TODO Auto-generated method stub          return  data.size();    }    @Override     public  Object getItem( int  position) {         //  TODO Auto-generated method stub          return  data.get(position);    }    @SuppressWarnings( " unchecked " )     public  String get( int  position, Object key) {        Map < String,  ?>  map  =  (Map < String,  ?> ) getItem(position);         return  map.get(key).toString();    }    @Override     public   long  getItemId( int  position) {         //  TODO Auto-generated method stub          return  position;    }    @Override     public  View getView( int  position, View convertView, ViewGroup parent) {         //  TODO Auto-generated method stub         convertView  =  mInflater.inflate(resource,  null );        Map < String,  ?>  item  =  data.get(position);         int  count  =  to.length;         for  ( int  i  =   0 ; i  <  count; i ++ ) {            View v  =  convertView.findViewById(to[i]);            bindView(v, item, from[i]);        }        convertView.setTag(position);         return  convertView;    }     /**      * 绑定视图     *  @param  view     *  @param  item     *  @param  from      */      private   void  bindView(View view, Map < String,  ?>  item, String from) {        Object data  =  item.get(from);         if  (view  instanceof  TextView) {            ((TextView) view).setText(data  ==   null   ?   ""  : data.toString());        }    }}

 

对应的XML 如下:

 

<? xml version="1.0" encoding="UTF-8" ?> < LinearLayout  xmlns:android ="http://schemas.android.com/apk/res/android"     android:orientation ="vertical"  android:layout_width ="fill_parent"     android:layout_height ="fill_parent" >      < TextView  android:id ="@+id/TextView01"         android:layout_marginLeft ="10px"  android:textAppearance ="?android:attr/textAppearanceLarge"         android:layout_width ="wrap_content"  android:layout_height ="wrap_content" >      </ TextView >      < TextView  android:id ="@+id/TextView02"  android:layout_width ="wrap_content"         android:textAppearance ="?android:attr/textAppearanceSmall"         android:layout_marginLeft ="10px"  android:layout_height ="wrap_content" >      </ TextView >      < View  android:layout_height ="1px"  android:background ="#FFFFFF"         android:layout_width ="fill_parent" ></ View > </ LinearLayout >

 

第三步:主页面使用控件并为其设置数据

XML如下:      < com.terry.widget.LinearLayoutForListView                         android:orientation ="vertical"  android:layout_width ="450px"                         android:layout_height ="fill_parent"  android:id ="@+id/ListView01" >                      </ com.terry.widget.LinearLayoutForListView >

 

加载数据如下: lv  =  (LinearLayoutForListView) findViewById(R.id.ListView01);         for  ( int  i  =   0 ; i  <   10 ; i ++ ) {            HashMap < String, Object >  map  =   new  HashMap < String, Object > ();            map.put( " key_name " " name "   +  i);            map.put( " value_name " " value "   +  i);            list.add(map);        }         final  AdapterForLinearLayout Layoutadpater  =   new  AdapterForLinearLayout(                 this , list, R.layout.test,  new  String[] {  " key_name " ,                         " value_name "  },  new   int [] { R.id.TextView01,                        R.id.TextView02 });

 

事件操作,并通过下标得到数据源: lv.setOnclickLinstener( new  OnClickListener() {            @Override             public   void  onClick(View v) {                 //  TODO Auto-generated method stub                 Toast.makeText(                        BlueToothActivity. this ,                        Layoutadpater.get(Integer.parseInt(v.getTag()                                .toString()),  " key_name " ),  1000 ).show();            }        });        lv.setAdapter(Layoutadpater);

 

Tip:get方法是在Layoutadpater 封装的一个通过下标获取相应数据的方法请参考上文。

至此完成。有碰到这个问题的朋友可以试试。

转载于:https://www.cnblogs.com/TerryBlog/archive/2010/08/13/1799045.html

相关资源:数据结构—成绩单生成器

最新回复(0)