zoukankan      html  css  js  c++  java
  • Android布局设计之ExpandableList绑定XML数据构成级联、item布局页面的控件查找及配置child事件,自定义适配显示内容

    研究了N久,Google,百度了找到些靠谱的和过滤了N多不靠谱,总算实现了ExpandableList绑定XML数据构成级联、item布局页面控件查找配置事件,自定义适配内容的功能,现在就分享给各个同学。

    效果:

     

     

    布局:

    main:

     

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:background="#ffffff"
        android:orientation="vertical" >
    
       
        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:layout_below="@id/title" >
    
            <ExpandableListView
                android:id="@id/android:list"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:cacheColorHint="#ffffffff"
                android:drawSelectorOnTop="false" />
    
            <TextView
                android:id="@id/android:empty"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"/>
        </LinearLayout>
    
    </RelativeLayout>

    group:

    <?xml version="1.0" encoding="UTF-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:padding="5dp" >
    
        <ImageView
            android:id="@+id/group_image"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:paddingLeft="30dp" />
    
        <TextView
            android:id="@+id/group_txt"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:paddingLeft="65dp"
            android:textColor="#000000"
            android:textSize="35sp" />
    
    </RelativeLayout>

    child:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:paddingLeft="20dp" >
    
        <ImageView
            android:id="@+id/child_image"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:paddingLeft="30dp"
            android:paddingTop="4dp" />
    
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical" >
    
            <TextView
                android:id="@+id/child_name"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="中国"
                android:textSize="30sp" />
    
            <TextView
                android:id="@+id/child_address"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="地址:xx省xx市xx" />
        </LinearLayout>
    
        <TextView
            android:id="@+id/child_id"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="地址:xx省xx市xx" />
    
    </LinearLayout>

    XML数据:

    商铺类型:

    <?xml version="1.0" encoding="UTF-8"?>
    <shoptypes>
        <shoptype id="1">
            <name>快餐店</name>
        </shoptype>
        <shoptype id="2">
            <name>小卖部</name>
        </shoptype>
        <shoptype id="3">
            <name>网吧</name>
        </shoptype>
        <shoptype id="4">
            <name>电器店</name>
        </shoptype>
        <shoptype id="5">
            <name>银行</name>
        </shoptype>
    </shoptypes>

    商铺:

    <?xml version="1.0" encoding="UTF-8"?>
    <shops>
        <shop id="1">
            <typeid>1</typeid>
            <name>好食膳</name>
            <adress>福州市XXX</adress>
        </shop>
        <shop id="2">
            <typeid>1</typeid>
            <name>好食膳</name>
            <adress>福州市XXX</adress>
        </shop>
        <shop id="3">
            <typeid>1</typeid>
            <name>好食膳</name>
            <adress>福州市XXX</adress>
        </shop>
        <shop id="4">
            <typeid>2</typeid>
            <name>实践部</name>
            <adress>福州市XXX</adress>
        </shop>
        <shop id="5">
            <typeid>2</typeid>
            <name>实践部</name>
            <adress>福州市XXX</adress>
        </shop>
        <shop id="6">
            <typeid>2</typeid>
            <name>实践部</name>
            <adress>福州市XXX</adress>
        </shop>
        <shop id="7">
            <typeid>2</typeid>
            <name>网络部</name>
            <adress>福州市XXX</adress>
        </shop>
        <shop id="8">
            <typeid>3</typeid>
            <name>网络部</name>
            <adress>福州市XXX</adress>
        </shop>
        <shop id="9">
            <typeid>3</typeid>
            <name>网络部</name>
            <adress>福州市XXX</adress>
        </shop>
        <shop id="10">
            <typeid>3</typeid>
            <name>卡狄工作室</name>
            <adress>福州市XXX</adress>
        </shop>
        <shop id="11">
            <typeid>4</typeid>
            <name>魔舟工作室</name>
            <adress>福州市XXX</adress>
        </shop>
        <shop id="12">
            <typeid>4</typeid>
            <name>魔舟工作室</name>
            <adress>福州市XXX</adress>
        </shop>
        <shop id="13">
            <typeid>4</typeid>
            <name>魔舟工作室</name>
            <adress>福州市XXX</adress>
        </shop>
        <shop id="14">
            <typeid>5</typeid>
            <name>好食膳</name>
            <adress>福州市XXX</adress>
        </shop>
        <shop id="15">
            <typeid>5</typeid>
            <name>好食膳</name>
            <adress>福州市XXX</adress>
        </shop>
    </shops>

    java:

    main:

    /**
     * 
     */
    package com.clshf.android.classify;
    
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    import com.clshf.android.R;
    import com.clshf.android.domain.Shop;
    import com.clshf.android.domain.ShopType;
    import com.clshf.android.services.AppXmlPaseService;
    import com.clshf.android.services.ExpandableListAdapterService;
    
    import android.app.ExpandableListActivity;
    import android.graphics.drawable.Drawable;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.ExpandableListView;
    import android.widget.ImageView;
    import android.widget.TextView;
    import android.widget.Toast;
    
    /**
     * 作用:分类窗体 创建时间:2012-8-3 上午10:29:53 修改时间:2012年8月10日17:02:16
     * 
     * @author Hzl520
     */
    public class ClassifyActivity extends ExpandableListActivity {
        
        private static final String GROUPPCITURE = "grouppciture";
    
        private static final String GROUPNAME = "groupname";
    
        private ExpandableListAdapterService exListAdapter = null;
    
        private static final String SUBCLASSNAMEID = "subclassid";
    
        private static final String SUBCLASSPICTURE = "subclasspicture";
    
        private static final String SUBCLASSNAME = "subclassname";
    
        private static final String SUBCLASSADDRESS = "subclassaddress";
    
     /*
         * 作用:窗体初始化.. 步骤:看注释 创建时间:2012-8-7 下午5:24:20 修改时间:2012-8-10 下午4:19:33
         * 
         * @param savedInstanceState
         */
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.classifyview);
    /** ==============配置风琴数据=============== **/ AppXmlPaseService appXmlPaseService = new AppXmlPaseService(); try { List<ShopType> shopTypes = appXmlPaseService.getPersons(this, "xml/shops/shoptype.xml"); List<Map<String, Object>> groupData = new ArrayList<Map<String, Object>>();// 父类数据 List<List<Map<String, Object>>> childData = new ArrayList<List<Map<String, Object>>>();// 子类数据 // 嵌套循环遍历数据填充至风琴列表中 for (ShopType shoptype : shopTypes) { HashMap<String, Object> curGroupMap = new HashMap<String, Object>(); groupData.add(curGroupMap); curGroupMap.put(GROUPPCITURE, R.drawable.iv_1);// 填充图片,这个随意放。 curGroupMap.put(GROUPNAME, shoptype.getName());// 填充XML中的名称 // 循环遍历子数据 List<Shop> shops = appXmlPaseService.getShops(this, "xml/shops/shop.xml"); List<Map<String, Object>> children = new ArrayList<Map<String, Object>>(); for (Shop shop : shops) { HashMap<String, Object> curChildMap = new HashMap<String, Object>(); int shoptypeid = shoptype.get_id(); if (shoptypeid != 0) { if (shoptypeid == shop.getTypeid()) { curChildMap.put(SUBCLASSPICTURE, R.drawable.iv_1); curChildMap.put(SUBCLASSNAMEID, shop.get_id() .toString()); curChildMap.put(SUBCLASSNAME, shop.getName()); curChildMap.put(SUBCLASSADDRESS, shop.getAddress()); children.add(curChildMap); } else { continue; } } } childData.add(children); } // 配置风琴列表数据 exListAdapter = new ExpandableListAdapterService( ClassifyActivity.this, groupData, R.layout.classify_group, new String[] { GROUPPCITURE, GROUPNAME }, new int[] { R.id.group_image, R.id.group_txt }, childData, R.layout.classify_child, new String[] { SUBCLASSPICTURE, SUBCLASSNAME, SUBCLASSADDRESS, SUBCLASSNAMEID }, new int[] { R.id.child_image, R.id.child_name, R.id.child_address, R.id.child_id }); // 设置风琴列表数据 setListAdapter(exListAdapter); } catch (Exception e) { e.printStackTrace(); } // 对图片ID进行处理 exListAdapter .setViewBinder(new ExpandableListAdapterService.ViewBinder() { /* * 作用:处理图片问题 步骤:看注释 创建时间:2012-8-10 下午4:19:29 修改时间:2012-8-10 * 下午4:19:29 * * @param view * * @param data * * @param textRepresentation * * @return */ @Override public boolean setViewValue(View view, Object data, String textRepresentation) { switch (view.getId()) { case R.id.group_image: { if (view instanceof ImageView) { ImageView _view = (ImageView) view; if (data instanceof Integer) { _view.setImageResource((Integer) data); } else if (data instanceof Drawable) { _view.setImageDrawable((Drawable) data); } else { throw new IllegalArgumentException( "The Data is Not a Drawable Or Resource Id!"); } } return true; } case R.id.child_image: { if (view instanceof ImageView) { ImageView _view = (ImageView) view; if (data instanceof Integer) { _view.setImageResource((Integer) data); } else if (data instanceof Drawable) { _view.setImageDrawable((Drawable) data); } else { throw new IllegalArgumentException( "The Data is Not a Drawable Or Resource Id!"); } } return true; } } return false; } }); } /* * 作用:处理子菜单点击事件 * 步骤:看注释 * 创建时间:2012-8-11 上午11:48:53 * 修改时间:2012-8-11 上午11:48:53 * @param parent * @param v * @param groupPosition * @param childPosition * @param id * @return */ @Override public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) { HashMap<String,String> map=(HashMap<String,String>)exListAdapter.getChild(groupPosition, childPosition); String sid=map.get(SUBCLASSNAMEID); Toast.makeText(this, "child--->"+sid,1).show(); return true; } }


    xml数据解析:

    /**
     * 
     */
    package com.clshf.android.services;
    
    import java.io.InputStream;
    import java.util.ArrayList;
    import java.util.List;
    
    import org.xmlpull.v1.XmlPullParser;
    
    import com.clshf.android.domain.Shop;
    import com.clshf.android.domain.ShopType;
    
    import android.content.Context;
    import android.util.Xml;
    
    
    /**
     * 作用:应用的XML数据解析处理
     * 创建时间:2012-8-10 上午10:34:30
     * 修改时间:2012-8-10 上午10:34:30
     * @author Hzl520
     */
    public class AppXmlPaseService {
    
    
        /**
         * 作用:获取assets文件中的shop数据
         * 步骤:看注释
         * 创建时间:2012-8-10 下午5:31:10
         * 修改时间:2012-8-10 下午5:31:10
         * @param context
         * @param assetspath
         * @return List<Shop>
         * @throws Exception
         */
        public  List<Shop> getShops(Context context,String assetspath ) throws Exception {
            //获取xml文件流对象
            InputStream inputStream=context.getAssets().open(assetspath);
            List<Shop> shops=null;
            Shop shop=null;
            XmlPullParser parser=Xml.newPullParser();
            parser.setInput(inputStream, "UTF-8");
            //获取解析事件,和SAX类似
            int eventType=parser.getEventType();
            //使用各个事件解析XML
            while(eventType!=XmlPullParser.END_DOCUMENT){
                switch (eventType) {
                case XmlPullParser.START_DOCUMENT:
                    //开始遍历节点的时候实例化集合
                    shops=new ArrayList<Shop>();
                    break;
                case XmlPullParser.START_TAG:
                    String name=parser.getName();
                    if(name.equals("shop")){
                        shop=new Shop();
                        shop.set_id(new Integer(parser.getAttributeValue(0)));
                    }
                    if (shop!=null) {
                        if (name.equals("typeid")) {
                            shop.setTypeid(new Integer(parser.nextText()));
                        }else if (name.equals("name")) {
                            shop.setName(parser.nextText());
                        }
                        else if (name.equals("adress")) {
                            shop.setAddress(parser.nextText());
                        }
                    }
                    break;
                case XmlPullParser.END_TAG:
                    if(parser.getName().equals("shop")){
                        shops.add(shop);
                        shop=null;
                        }
                    break;
                }
                //遍历下一个节点
                eventType=parser.next();
            }
            return shops;
        }
    
    
        /**
         * 作用:从XML中获取商店类型信息
         * 步骤:看注释
         * 创建时间:2012-7-14 上午10:31:25
         * 修改时间:2012-7-14 上午10:31:25
         * @param inputStream
         * @return
         * @throws Exception 
         */
        public  List<ShopType> getPersons(Context context,String assetspath ) throws Exception {
            //获取xml文件流对象
            InputStream inputStream=context.getAssets().open(assetspath);
            List<ShopType> shoptypes=null;
            ShopType shoptype=null;
            XmlPullParser parser=Xml.newPullParser();
            parser.setInput(inputStream, "UTF-8");
            //获取解析事件,和SAX类似
            int eventType=parser.getEventType();
            //使用各个事件解析XML
            while(eventType!=XmlPullParser.END_DOCUMENT){
                switch (eventType) {
                case XmlPullParser.START_DOCUMENT:
                    //开始遍历节点的时候实例化集合
                    shoptypes=new ArrayList<ShopType>();
                    break;
                case XmlPullParser.START_TAG:
                    String name=parser.getName();
                    if(name.equals("shoptype")){
                        shoptype=new ShopType();
                        shoptype.set_id(new Integer(parser.getAttributeValue(0)));
                    }
                    if (shoptype!=null) {
                        if (name.equals("name")) {
                            shoptype.setName(parser.nextText());
                        }
                    }
                    break;
                case XmlPullParser.END_TAG:
                    if(parser.getName().equals("shoptype")){
                        shoptypes.add(shoptype);
                        shoptype=null;
                        }
                    break;
                }
                //遍历下一个节点
                eventType=parser.next();
            }
            return shoptypes;
        }
        
    }

    ExpandableList数据适配器:

    package com.clshf.android.services;
    
    import android.content.Context;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.BaseExpandableListAdapter;
    import android.widget.TextView;
    
    import java.util.List;
    import java.util.Map;
    
    /**
     * 作用:自定义处理ExpandableListAdapter数据
     * 创建时间:2012-8-10 下午3:30:09
     * 修改时间:2012-8-10 下午3:30:09
     * @author Hzl520
     */
    public class ExpandableListAdapterService extends BaseExpandableListAdapter {
        private ViewBinder mViewBinder;
    
        private List<? extends Map<String, ?>> mGroupData;
        private int mExpandedGroupLayout;
        private int mCollapsedGroupLayout;
        private String[] mGroupFrom;
        private int[] mGroupTo;
    
        private List<? extends List<? extends Map<String, ?>>> mChildData;
        private int mChildLayout;
        private int mLastChildLayout;
        private String[] mChildFrom;
        private int[] mChildTo;
    
        private LayoutInflater mInflater;
    
        public ExpandableListAdapterService(Context context, List<? extends Map<String, ?>> groupData,
                int groupLayout, String[] groupFrom, int[] groupTo,
                List<? extends List<? extends Map<String, ?>>> childData, int childLayout,
                String[] childFrom, int[] childTo) {
            this(context, groupData, groupLayout, groupLayout, groupFrom, groupTo, childData,
                    childLayout, childLayout, childFrom, childTo);
        }
    
        public ExpandableListAdapterService(Context context, List<? extends Map<String, ?>> groupData,
                int expandedGroupLayout, int collapsedGroupLayout, String[] groupFrom, int[] groupTo,
                List<? extends List<? extends Map<String, ?>>> childData, int childLayout,
                String[] childFrom, int[] childTo) {
            this(context, groupData, expandedGroupLayout, collapsedGroupLayout, groupFrom, groupTo,
                    childData, childLayout, childLayout, childFrom, childTo);
        }
    
        public ExpandableListAdapterService(Context context, List<? extends Map<String, ?>> groupData,
                int expandedGroupLayout, int collapsedGroupLayout, String[] groupFrom, int[] groupTo,
                List<? extends List<? extends Map<String, ?>>> childData, int childLayout,
                int lastChildLayout, String[] childFrom, int[] childTo) {
            mGroupData = groupData;
            mExpandedGroupLayout = expandedGroupLayout;
            mCollapsedGroupLayout = collapsedGroupLayout;
            mGroupFrom = groupFrom;
            mGroupTo = groupTo;
    
            mChildData = childData;
            mChildLayout = childLayout;
            mLastChildLayout = lastChildLayout;
            mChildFrom = childFrom;
            mChildTo = childTo;
    
            mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        }
    
        public Object getChild(int groupPosition, int childPosition) {
            return mChildData.get(groupPosition).get(childPosition);
        }
    
        public long getChildId(int groupPosition, int childPosition) {
            return childPosition;
        }
    
        /**
         * Instantiates a new View for a child.
         * @param isLastChild Whether the child is the last child within its group.
         * @param parent The eventual parent of this new View.
         * @return A new child View
         */
        public View newChildView(boolean isLastChild, ViewGroup parent) {
            return mInflater.inflate((isLastChild) ? mLastChildLayout : mChildLayout, parent, false);
        }
    
        public int getChildrenCount(int groupPosition) {
            return mChildData.get(groupPosition).size();
        }
    
        public Object getGroup(int groupPosition) {
            return mGroupData.get(groupPosition);
        }
    
        public int getGroupCount() {
            return mGroupData.size();
        }
    
        public long getGroupId(int groupPosition) {
            return groupPosition;
        }
    
        /**
         * Instantiates a new View for a group.
         * @param isExpanded Whether the group is currently expanded.
         * @param parent The eventual parent of this new View.
         * @return A new group View
         */
        public View newGroupView(boolean isExpanded, ViewGroup parent) {
            return mInflater.inflate((isExpanded) ? mExpandedGroupLayout : mCollapsedGroupLayout,
                    parent, false);
        }
    
        public boolean isChildSelectable(int groupPosition, int childPosition) {
            return true;
        }
    
        public boolean hasStableIds() {
            return true;
        }
    
        // --------------------------------------------------------------------------------------//
    
        private void bindView(View view, Map<String, ?> data, String[] from, int[] to) {
            int len = to.length;
    
            boolean isBound = false;
            for (int i = 0; i < len; i++) {
    
                final View v = view.findViewById(to[i]);
    
                if (v!=null) {
                    final Object _data = data.get(from[i]);
                    String text = _data == null ? "" : data.toString();
                    if (text == null) {
                        text = "";
                    }
                    
                    if (mViewBinder != null) {//如果Binder不为空,使用Binder进行处理
                        isBound = mViewBinder.setViewValue(v, data.get(from[i]), text);
                    }
                    
                    if (!isBound) {//如果Binder跳过,使用原来的方法进行处理
                        TextView _v = (TextView)v;
                        _v.setText((String)data.get(from[i]));
                    }                
                }
            }
        }
    
        public View getGroupView(int groupPosition, boolean isExpanded, View convertView,
                ViewGroup parent) {
            View v;
            if (convertView == null) {
                v = newGroupView(isExpanded, parent);
            } else {
                v = convertView;
            }
    
            bindView(v, mGroupData.get(groupPosition), mGroupFrom, mGroupTo);
            return v;
        }
    
        public View getChildView(int groupPosition, int childPosition, boolean isLastChild,
                View convertView, ViewGroup parent) {
            View v;
            if (convertView == null) {
                v = newChildView(isLastChild, parent);
            } else {
                v = convertView;
            }
    
            bindView(v, mChildData.get(groupPosition).get(childPosition), mChildFrom, mChildTo);
            return v;
        }
    
        public void setViewBinder(ViewBinder mViewBinder) {
            this.mViewBinder = mViewBinder;
        }
    
        /**
         * 作用:提供视图渲染的绑定器 
         * 创建时间:2012-8-10 下午3:29:45
         * 修改时间:2012-8-10 下午3:29:45
         * @author Hzl520
         */
        public static interface ViewBinder {
            boolean setViewValue(View view, Object data, String textRepresentation);
        }
    
    }

    转载请注明:http://www.cnblogs.com/hzl512/archive/2012/08/11/2633664.html

  • 相关阅读:
    Oracle Pagination
    JAVA JSP WebContent
    Java程序员面试可能遭遇的30个技术陷阱解析
    分布式缓存系统Memcached
    java注解入门实例
    JSTL JSP Tag介绍
    注意事项
    Powershell打开、关闭VS
    IE和FF的差异(js版本)
    javascript 权威指南(09)
  • 原文地址:https://www.cnblogs.com/hzl512/p/2633664.html
Copyright © 2011-2022 走看看