Android 解决ListView 和 ScrollView 共存冲突的问题(另一种解决方案) – android大牛MrJing 活动中心 – 博客频道 – CSDN.NET

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, nullnull);

            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_namename + i);

                map.put(value_namevalue + 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 封装的一个通过下标获取相应数据的方法请参考上文。

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

来源URL:http://cache.baiducontent.com/c?m=9d78d513d9901df918b0cf281a16a6204e1ec6743da7944e28918448e23a00000122b8ec62351174c4b57c7071df5e5d9ae74774207551a09ab89f3ad6ace22838f8212307189206528d16f58d0067d621e347f4ff47baefe732e4ff9385834353bd0f523c9da8d00655519d33f1103ae8bbca08530441e4ba2d33a81f2472c1625db342f3ea306d0d&p=882a924f999e12a05abb8a22464c&newp=8b2a970e929507b51cbd9b79074b92695803ed6338d0d75e3b82d552d7&user=baidu&fm=sc&query=android+textview+listview%B2%BB%C4%DC%B9%B2%B4%E6&qid=950fbbb70001b2fe&p1=1