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

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

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

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

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

 

<!--<br/ /> <br/ /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ /> http://www.CodeHighlighter.com/<br/ /> <br/ /> --> public LinearLayoutForListView(Context context) {
super (context);

}

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

}

 

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

为其添加get / set 方法

<!--<br/ /> <br/ /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ /> http://www.CodeHighlighter.com/<br/ /> <br/ /> --> /**
* 获取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,并为其添加构造函数

 

<!--<br/ /> <br/ /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ /> http://www.CodeHighlighter.com/<br/ /> <br/ /> --> 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,代码如下:

 

<!--<br/ /> <br/ /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ /> http://www.CodeHighlighter.com/<br/ /> <br/ /> --> @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

<!--<br/ /> <br/ /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ /> http://www.CodeHighlighter.com/<br/ /> <br/ /> --> 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

<!--<br/ /> <br/ /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ /> http://www.CodeHighlighter.com/<br/ /> <br/ /> --> 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 如下:

 

<!--<br/ /> <br/ /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ /> http://www.CodeHighlighter.com/<br/ /> <br/ /> --> <? 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如下:
    <!--<br/ /> <br/ /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ /> http://www.CodeHighlighter.com/<br/ /> <br/ /> --> < com.terry.widget.LinearLayoutForListView
    android:orientation ="vertical" android:layout_width ="450px"
    android:layout_height
    ="fill_parent" android:id ="@+id/ListView01" >
    </ com.terry.widget.LinearLayoutForListView >

     

  • 加载数据如下:
    <!--<br/ /> <br/ /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ /> http://www.CodeHighlighter.com/<br/ /> <br/ /> --> 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 });

     

  • 事件操作,并通过下标得到数据源:
    <!--<br/ /> <br/ /> Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ /> http://www.CodeHighlighter.com/<br/ /> <br/ /> --> 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 封装的一个通过下标获取相应数据的方法请参考上文。

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

 

原文:http://terryblog.blog.51cto.com/1764499/373509

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值