本文内容

  • 环境
  • 项目结构
  • 演示 1:简单 XListView
  • 演示 2:XListView + Fragment
  • 演示 3:XListView + ViewPager + Fragment

本文三个演示,循序渐进。

  • 演示 1 是 GitHub 上的 XListView 控件,具备“下拉更新”和“上拉加载”功能,使用它自己的示例;
  • 演示 2 是将 XListView 控件封装到 Fragment 中,个人认为,这种封装在实际项目还是比较常用的;
  • 演示 3 是进一步将 XListView 与 ViewPager 和 Fragment 相结合。也就是在演示 2 基础上,每个 ViewPager 的页都是 XListView 和 Fragment。

下载 Demo

更多 Demo

环境


  • Windows 2008 R2 64 位
  • Eclipse ADT V22.6.2,Android 4.4.2(API 19)
  • SAMSUNG GT-8618,Android OS 4.1.2

项目结构


图 1 项目结构和主程序界面

演示 1:简单 XListView


这是 github 上的一个项目。本演示,只是简单说明它的功能。

图 2 演示 1

package com.wallace.xlistview.ui;

 

import java.util.ArrayList;

 

import com.wallace.xlistview.R;

import com.wallace.xlistview.widget.XListView;

import com.wallace.xlistview.widget.XListView.IXListViewListener;

 

import android.app.Activity;

import android.os.Bundle;

import android.os.Handler;

import android.view.View;

import android.widget.AdapterView;

import android.widget.AdapterView.OnItemClickListener;

import android.widget.AdapterView.OnItemSelectedListener;

import android.widget.ArrayAdapter;

import android.widget.Toast;

 

public class XListSimpleActivity extends Activity implements IXListViewListener {

    private XListView mListView;

    private ArrayAdapter<String> mAdapter;

    private ArrayList<String> items = new ArrayList<String>();

    private Handler mHandler;

    private int start = 0;

    private static int refreshCnt = 0;

 

    @Override

    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_simple);

 

        geneItems();

 

        initClass();

 

        initControl();

 

        initXList();

 

    }

 

    private void geneItems() {

        for (int i = 0; i != 20; ++i) {

            items.add("refresh cnt " + (++start));

        }

    }

 

    private void initClass() {

        mHandler = new Handler();

    }

 

    private void initControl() {

        mListView = (XListView) findViewById(R.id.xListView_a);

        mAdapter = new ArrayAdapter<String>(this, R.layout.xlist_simpleitem,

                items);

    }

 

    private void initXList() {

        mListView.setPullLoadEnable(true);

        mListView.setPullRefreshEnable(true);

        mListView.setAdapter(mAdapter);

        mListView.setXListViewListener(this);

        mListView.setOnItemClickListener(new OnItemClickListener() {

 

            @Override

            public void onItemClick(AdapterView<?> parent, View view,

                    int position, long id) {

 

                Toast.makeText(getApplicationContext(), items.get(position),

                        Toast.LENGTH_SHORT).show();

            }

        });

        mListView.setOnItemSelectedListener(new OnItemSelectedListener() {

 

            @Override

            public void onItemSelected(AdapterView<?> parent, View view,

                    int position, long id) {

                Toast.makeText(getApplicationContext(), items.get(position),

                        Toast.LENGTH_SHORT).show();

            }

 

            @Override

            public void onNothingSelected(AdapterView<?> parent) {

            }

        });

    }

 

    private void onLoad() {

        mListView.stopRefresh();

        mListView.stopLoadMore();

        mListView.setRefreshTime("刚刚");

    }

 

    // Refresh

    @Override

    public void onRefresh() {

        mHandler.postDelayed(new Runnable() {

            @Override

            public void run() {

                start = ++refreshCnt;

                items.clear();

                geneItems();

                // mAdapter.notifyDataSetChanged();

                mAdapter = new ArrayAdapter<String>(XListSimpleActivity.this,

                        R.layout.xlist_simpleitem, items);

                mListView.setAdapter(mAdapter);

                onLoad();

            }

        }, 2000);

    }

 

    // LoadMore

    @Override

    public void onLoadMore() {

        mHandler.postDelayed(new Runnable() {

            @Override

            public void run() {

                geneItems();

                mAdapter.notifyDataSetChanged();

                onLoad();

            }

        }, 2000);

    }

}

演示 2:XListView + Fragment


接下来,我就在想,如何将 XListView 放到 Fragment 中,毕竟实际项目中,这种情况可能会多点,这样,就能将 Fragment 放到 FrameLayout 里。顺便把数据换成自己的。

图 3 演示 2

package com.wallace.xlistview.view;

 

import java.util.ArrayList;

import java.util.List;

 

import com.wallace.xlistview.R;

import com.wallace.xlistview.dao.MusicDao;

import com.wallace.xlistview.entity.MusicItemEntity;

import com.wallace.xlistview.utils.ImageLoader;

import com.wallace.xlistview.widget.XListView;

import com.wallace.xlistview.widget.XListView.IXListViewListener;

 

import android.annotation.SuppressLint;

import android.app.Activity;

import android.content.Context;

import android.os.AsyncTask;

import android.os.Bundle;

import android.os.Handler;

import android.support.v4.app.Fragment;

import android.view.LayoutInflater;

import android.view.View;

import android.view.ViewGroup;

import android.widget.BaseAdapter;

import android.widget.ImageView;

import android.widget.TextView;

 

@SuppressLint({ "ValidFragment", "HandlerLeak" })

public class MusicXListFragment extends Fragment implements IXListViewListener {

 

    protected List<MusicItemEntity> musics = null;

    private MusicDao musicDao;

    protected Activity mActivity;

    protected XListView listview;

    protected NewXListFragmentAdapter mAdapter;

    protected View view;

    public LayoutInflater mInflater;

    private Handler mHandler;

 

    public MusicXListFragment(Activity c, List<MusicItemEntity> list) {

        this.mActivity = c;

 

        if (list != null) {

            this.musics = list;

        }

    }

 

    @Override

    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        mHandler = new Handler();

        musicDao = new MusicDao(this.mActivity);

    }

 

    @Override

    public View onCreateView(LayoutInflater inflater, ViewGroup container,

            Bundle savedInstanceState) {

        super.onCreateView(inflater, container, savedInstanceState);

        mInflater = inflater;

        view = inflater.inflate(R.layout.xlist_main, null);

        listview = (XListView) view.findViewById(R.id.xListView_b);

        listview.setPullLoadEnable(true);

        listview.setPullRefreshEnable(true);

        listview.setXListViewListener(this);

        mAdapter = new NewXListFragmentAdapter(mActivity, this.musics);

        listview.setAdapter(mAdapter);

        return view;

    }

 

    @Override

    public void onSaveInstanceState(Bundle outState) {

        super.onSaveInstanceState(outState);

    }

 

    protected void onLoad() {

        listview.stopRefresh();

        listview.stopLoadMore();

        listview.setRefreshTime("刚刚");

    }

 

    /**

     * onRefresh

     */

    @Override

    public void onRefresh() {

        mHandler.postDelayed(new Runnable() {

            @Override

            public void run() {

                new MyTask().execute(musicDao);

                onLoad();

            }

        }, 2000);

    }

 

    /**

     * onLoadMore

     */

    @Override

    public void onLoadMore() {

        mHandler.postDelayed(new Runnable() {

            @Override

            public void run() {

                new MyTask().execute(musicDao);

                onLoad();

            }

        }, 2000);

    }

 

    class NewXListFragmentAdapter extends BaseAdapter {

 

        private Activity activity;

        private LayoutInflater inflater = null;

        public ImageLoader imageLoader;

        private List<MusicItemEntity> musics;

 

        public NewXListFragmentAdapter(List<MusicItemEntity> lists) {

 

            musics = lists;

            inflater = (LayoutInflater) activity

                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

            imageLoader = new ImageLoader(activity.getApplicationContext());

        }

 

        public NewXListFragmentAdapter(Activity a, List<MusicItemEntity> lists) {

            activity = a;

            musics = lists;

            inflater = (LayoutInflater) activity

                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

            imageLoader = new ImageLoader(activity.getApplicationContext());

        }

 

        public void appendToList(List<MusicItemEntity> lists) {

 

            if (lists == null) {

                return;

            }

            if (musics == null) {

                musics = new ArrayList<MusicItemEntity>();

            }

            musics.addAll(lists);

            notifyDataSetChanged();

        }

 

        public int getCount() {

            return musics == null ? 0 : musics.size();

        }

 

        public Object getItem(int position) {

            return position;

        }

 

        public long getItemId(int position) {

            return position;

        }

 

        public View getView(int position, View convertView, ViewGroup parent) {

            View vi = convertView;

            if (convertView == null)

                vi = inflater.inflate(R.layout.xlist_row, null);

 

            MusicItemEntity song = null;

 

            ImageView image = (ImageView) vi.findViewById(R.id.imagethumb);

            TextView tvartist = (TextView) vi.findViewById(R.id.artist);

            TextView tvtitle = (TextView) vi.findViewById(R.id.title);

            TextView tvduration = (TextView) vi.findViewById(R.id.duration);

 

            song = musics.get(position);

            imageLoader.DisplayImage(song.getThumbUrl(), image);

            tvartist.setText(song.getArtist());

            tvtitle.setText(song.getTitle());

            tvduration.setText(song.getDuration());

 

            return vi;

        }

    }

    

    /**

     * MyTask

     */

    public class MyTask extends

            AsyncTask<MusicDao, String, List<MusicItemEntity>> {

 

        public MyTask() {

        }

 

        public MyTask(boolean useCache) {

        }

 

        @Override

        protected void onPreExecute() {

            super.onPreExecute();

        }

 

        @Override

        protected List<MusicItemEntity> doInBackground(MusicDao... params) {

            MusicDao dao = params[0];

            List<MusicItemEntity> list = dao.getMore();

            return list;

        }

 

        @Override

        protected void onPostExecute(List<MusicItemEntity> result) {

            // TODO Auto-generated method stub

            super.onPostExecute(result);

            mAdapter.appendToList(result);

            mAdapter.notifyDataSetChanged();

        }

    }

}

说明:当然,你也可以把 NewXListFragmentAdapter 类单独写成一个 .java 文件,这里只是为了演示方便,但是 Demo 里是独立的。

演示 3:XListView + ViewPager + Fragment


然后再想,在演示 2 基础上,每个 Fragment 如何变成 ViewPager 的一页。

图 4 演示 3

package com.wallace.xlistview.ui;

 

import java.util.ArrayList;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

 

import com.wallace.xlistview.R;

//import com.wallace.xlistview.adapter.NewXListPageFragmentAdapter;

import com.wallace.xlistview.dao.MusicDao;

import com.wallace.xlistview.entity.CategorysEntity;

import com.wallace.xlistview.entity.MusicList;

import com.wallace.xlistview.view.HttpErrorFragment;

import com.wallace.xlistview.view.MusicXListFragment;

 

import android.app.Activity;

import android.os.AsyncTask;

import android.os.Bundle;

import android.support.v4.app.Fragment;

import android.support.v4.app.FragmentActivity;

import android.support.v4.app.FragmentManager;

import android.support.v4.app.FragmentStatePagerAdapter;

import android.support.v4.view.PagerTabStrip;

import android.support.v4.view.ViewPager;

import android.util.Log;

import android.view.ViewGroup;

import android.view.Window;

 

public class XListPagerFragmentActivity extends FragmentActivity {

 

    private ViewPager mViewPager;

    private NewXListPageFragmentAdapter mBasePageAdapter;

    private PagerTabStrip mPagerTabStrip;

    private List<MusicList> categoryList;

    private MusicDao musicDao;

 

    @Override

    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        requestWindowFeature(Window.FEATURE_NO_TITLE);

        setContentView(R.layout.activity_viewpager);

 

        initClass();

 

        initControl();

 

        initViewPager();

    }

 

    private void initControl() {

        mViewPager = (ViewPager) findViewById(R.id.above_pager);

        mPagerTabStrip = (PagerTabStrip) findViewById(R.id.myPagerTabStrip);

    }

 

    private void initClass() {

        musicDao = new MusicDao(this);

        mBasePageAdapter = new NewXListPageFragmentAdapter(

                this.getSupportFragmentManager());

        mBasePageAdapter.setActvity(XListPagerFragmentActivity.this);

    }

 

    private void initViewPager() {

        mPagerTabStrip.setTabIndicatorColor(getResources()

                .getColor(R.color.red));

        mPagerTabStrip.setDrawFullUnderline(false);

        mPagerTabStrip.setBackgroundColor(getResources()

                .getColor(R.color.green));

        // mPagerTabStrip.setTextSpacing(50);

 

        mViewPager.setOffscreenPageLimit(0);

        mViewPager.setAdapter(mBasePageAdapter);

 

        new MyTask().execute(musicDao);

    }

 

    /* execute after killed */

    @Override

    public void onSaveInstanceState(Bundle outState) {

        super.onSaveInstanceState(outState);

    }

 

    class NewXListPageFragmentAdapter extends FragmentStatePagerAdapter {

 

        public ArrayList<Fragment> mFragments = new ArrayList<Fragment>();

        public List<CategorysEntity> tabs = new ArrayList<CategorysEntity>();

 

        private Activity mActivity;

 

        public NewXListPageFragmentAdapter(FragmentManager fragmentManager) {

            // TODO Auto-generated constructor stub

            super(fragmentManager);

        }

 

        public void setActvity(Activity a) {

            this.mActivity = a;

        }

 

        public void addFragment(List<CategorysEntity> mList,

                List<MusicList> listObject) {

            tabs.addAll(mList);

            for (int i = 0; i < listObject.size(); i++) {

                MusicList musics = listObject.get(i);

                addTab(new MusicXListFragment(mActivity, musics.getMusics()));

            }

        }

 

        /**

         * only load listview, donot include tabs

         * 

         * @param listObject

         */

        public void addFragment(List<MusicList> listObject) {

            for (int i = 0; i < listObject.size(); i++) {

                MusicList musics = listObject.get(i);

                addTab(new MusicXListFragment(mActivity, musics.getMusics()));

            }

        }

 

        public void addNullFragment() {

            CategorysEntity cate = new CategorysEntity();

            cate.setName("connect error");

            tabs.add(cate);

            addTab(new HttpErrorFragment());

        }

 

        public void Clear() {

            mFragments.clear();

            tabs.clear();

        }

 

        public void addTab(Fragment fragment) {

            mFragments.add(fragment);

            notifyDataSetChanged();

        }

 

        @Override

        public CharSequence getPageTitle(int position) {

            Log.d("vp-getPageTitle", tabs.get(position).getName());

            return tabs.get(position).getName();

        }

 

        @Override

        public Fragment getItem(int arg0) {

            Log.d("vp-getItem", String.format("%s", arg0));

            return mFragments.get(arg0);

        }

 

        // 初始化每个页卡选项

        @Override

        public Object instantiateItem(ViewGroup arg0, int position) {

            Log.d("vp-instantiateItem", String.format("%s", position));

            return super.instantiateItem(arg0, position);

        }

 

        @Override

        public int getCount() {

            Log.d("vp-instantiateItem", String.format("%s", mFragments.size()));

            return mFragments.size();

        }

 

        @Override

        public void destroyItem(ViewGroup container, int position, Object object) {

            // TODO Auto-generated method stub

            super.destroyItem(container, position, object);

        }

    }

 

    public class MyTask extends

            AsyncTask<MusicDao, String, Map<String, Object>> {

 

        public MyTask() {

        }

 

        public MyTask(boolean useCache) {

        }

 

        @Override

        protected void onPreExecute() {

            mViewPager.removeAllViews();

            mBasePageAdapter.Clear();

            super.onPreExecute();

        }

 

        @Override

        protected Map<String, Object> doInBackground(MusicDao... params) {

            MusicDao dao = params[0];

            List<CategorysEntity> categorys = new ArrayList<CategorysEntity>();

            Map<String, Object> map = new HashMap<String, Object>();

 

            if ((categoryList = dao.getClassEntity()) != null) {

                categorys = dao.getCategorys();

                map.put("tabs", categorys);

                map.put("list", categoryList);

            }

 

            return map;

            // return null;

        }

 

        @SuppressWarnings("unchecked")

        @Override

        protected void onPostExecute(Map<String, Object> result) {

            // TODO Auto-generated method stub

            super.onPostExecute(result);

            mBasePageAdapter.Clear();

            mViewPager.removeAllViews();

            if (result != null && !result.isEmpty()) {

                mBasePageAdapter.addFragment(

                        (List<CategorysEntity>) result.get("tabs"),

                        (List<MusicList>) result.get("list"));

            } else {

                mBasePageAdapter.addNullFragment();

            }

            mBasePageAdapter.notifyDataSetChanged();

            mViewPager.setCurrentItem(0);

        }

    }

}

说明:当然,你也可以把 NewXListPageFragmentAdapter 类单独写成一个 .java 文件,这里只是为了演示方便,但是 Demo 里是独立的。

注意:演示 3 是有问题的,不知道为什么 ViewPager 每页的名字显示不出来。

Android 演示 Android ListView 和 github XListView(1-3)

Android github XListView 分析(2-3)

下载 Demo

Android 演示 Android ListView 和 github XListView(3-3)的更多相关文章

  1. Android 演示 Android ListView 和 github XListView(1-3)

    本文内容 环境 项目结构 演示 1:ListView 演示 2:简单 XListView 演示 3:音乐列表 XListView 演示 4:另一个音乐列表 XListView 本文四个演示,循序渐进. ...

  2. Android github XListView 分析(2-3)

    本文内容 概述 XListView UML 图 下载 github XListView 概述 我们经常能见到 app 中的 listview 有"下拉更多"和"上拉加载& ...

  3. Android开发之ListView添加多种布局效果演示

    在这个案例中展示的新闻列表,使用到ListView控件,然后在适配器中添加多种布局效果,这里通过重写BaseAdapter类中的 getViewType()和getItemViewType()来做判断 ...

  4. android 很多牛叉布局github地址(转)

    原文地址 http://blog.csdn.net/luo15309823081/article/details/41449929 点击可到达github-------https://github.c ...

  5. Android—自定义控件实现ListView下拉刷新

    这篇博客为大家介绍一个android常见的功能——ListView下拉刷新(参考自他人博客,网址忘记了,阅读他的代码自己理解注释的,希望能帮助到大家): 首先下拉未松手时候手机显示这样的界面: 下面的 ...

  6. 实例演示Android异步加载图片

    本文给大家演示异步加载图片的分析过程.让大家了解异步加载图片的好处,以及如何更新UI.首先给出main.xml布局文件:简单来说就是 LinearLayout 布局,其下放了2个TextView和5个 ...

  7. 实例演示Android异步加载图片(转)

    本文给大家演示异步加载图片的分析过程.让大家了解异步加载图片的好处,以及如何更新UI.首先给出main.xml布局文件:简单来说就是 LinearLayout 布局,其下放了2个TextView和5个 ...

  8. Android中使用ListView实现分页刷新(线程休眠模拟)(滑动加载列表)

    当要显示的数据过多时,为了更好的提升用户感知,在很多APP中都会使用分页刷新显示,比如浏览新闻,向下滑动到当前ListView的最后一条信息(item)时,会提示刷新加载,然后加载更新后的内容.此过程 ...

  9. Android中实现ListView圆角效果[转]

    本文演示如何Android中实现ListView圆角效果. 无论是网站,还是APP,人们都爱看一些新颖的视图效果.直角看多了,就想看看圆角,这几年刮起了一阵阵的圆角设计风:CSS新标准纳入圆角元素,特 ...

随机推荐

  1. Revit API遍历系统族布置喷头

    系统族可以通过内参遍历,遍历出来是个FamilySymbol喷头属于系统族,但不能通过NewDuct();类似这样的方法布置.必须使用 NewFamilyInstance() );           ...

  2. 基于设备树的TQ2440 DMA学习(3)—— DMA控制器驱动

    作者 彭东林pengdonglin137@163.com 平台 TQ2440Linux-4.9 概述 上一篇直接操作DMA控制器实现了一个mem2mem的DMA传输,但是这样不符合linux driv ...

  3. ASP.NET Web API中实现版本的几种方式

    在ASP.NET Web API中,当我们的API发生改变,就涉及到版本问题了.如何实现API的版本呢? 1.通过路由设置版本 最简单的一种方式是通过路由设置,不同的路由,不同的版本,不同的contr ...

  4. lodash用法系列(5),链式

    Lodash用来操作对象和集合,比Underscore拥有更多的功能和更好的性能. 官网:https://lodash.com/引用:<script src="//cdnjs.clou ...

  5. 测试RemObjects Pascal Script

    unit Unit1; interface usesWindows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, ...

  6. 直接将DataTable存入oracle数据库中(转)

    注意 1:传入的DataTable的列必须和数据库中表列必须一致,否则数据会默认往前几列存 2:sql语句只要是对要插入的表的一个查询,目的是为了确定表名 3:取得连接字符串的方法为GetOracle ...

  7. Android Initializing a Build Environment

    from://https://source.android.com/source/initializing.html#next-download-the-source Initializing a B ...

  8. IIS回收后首次访问慢问题

    禁用时间间隔回收 设置为0 然后设置指定时间回收 0:00:00 然后设置脚本 @echo off @echo 正在关掉所有的IE进程(需要设置默认浏览器是IE) taskkill /im iexpl ...

  9. 通过Selector来设置按钮enable/unable状态的样式

    我们可以用selector来配置button可用或者不可用时的背景,也可以用它来配置button不同状态下的文字颜色.下面左图是可用状态,右图是不可用状态.    一.配置按钮不同状态的背景 首先我们 ...

  10. 代码实现Android5.0的下拉刷新效果

    如图所示,实现类似与gmail的下拉刷新. 项目地址:https://github.com/stormzhang/SwipeRefreshLayoutDemo 一.在xml文件中定义 这个控件在sup ...