首页 > 学院 > 开发设计 > 正文

教你使用HorizontalScrollView和ListView打造左右和上下都可以滑动的列表布局

2019-11-09 16:39:46
字体:
来源:转载
供稿:网友

在项目的进行中要用到左右滑动又能上下滑动的列表布局,开始想的是使用一个ViewPager嵌套一个ListView来进行分页处理,在滑动ViewPager的时候翻页,效果是达到了,但是拓展性不好,所以我又另想法子,现在使用一个HorizontalScrollView嵌套一个ListView可以很好的解决拓展的问题,效果如下,原谅我GIF做的如此的简陋,这里提供一个思路,希望能帮到有需要的朋友,源代码附在文后大笑

  

    简单讲下实现的思路:思路应该从需求开始讲,项目中用到的这个类似电影院选座位或考场编座位,界面上有xx排xx列个位置,需要按照票面的座位号对号入座,如果一个屏幕能装下还好解决,使用GridView就应该可以应付了,但是如果横向超出一个屏幕,好像GridView就有点无能为力了,所以我这里思考使用HorizontalScorllView嵌套一层布局去实现,里面的布局我使用的是ListView,实现竖向滑动,不要问为什么,我喜欢,就是这么任性得意,当然如果你喜欢使用GridView,请随意大笑,因为他们俩都是AbsListVIew的直接子类,用法的话自己去琢磨大笑

二话不说先上代码了,这次从布局看起

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:id="@+id/activity_main"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:paddingBottom="@dimen/activity_vertical_margin"    android:paddingLeft="@dimen/activity_horizontal_margin"    android:paddingRight="@dimen/activity_horizontal_margin"    android:paddingTop="@dimen/activity_vertical_margin"    tools:context="com.cjt.horizontalscrollviewdemo.MainActivity">    <HorizontalScrollView        android:id="@+id/mHorizontalScrollView"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:layout_alignParentLeft="true"        android:layout_alignParentStart="true"        android:layout_alignParentTop="true">        <LinearLayout            android:layout_width="match_parent"            android:layout_height="match_parent"            android:orientation="vertical">            <LinearLayout                android:id="@+id/titleLayout"                android:orientation="horizontal"                android:layout_width="match_parent"                android:layout_height="40dp"/>            <ListView                android:id="@+id/mListView"                android:layout_width="match_parent"                android:layout_height="match_parent" />        </LinearLayout>    </HorizontalScrollView></RelativeLayout>
这就是我的主页面布局文件,在HorizontalScrollView中嵌套ListView布局,使用ScrollView或者HorizontalScrollView的时候一定要注意,因为他们比较特别,只承认一个儿子,也就是嵌套的子布局只能是一个,所以我这里使用的是LinearLayout包裹ListView控件,可能细心的你会问,还有一个LinearLayout是干嘛的,其实他不只是打酱油的,他就是上面GIF中的第几列的标题,ListView上下滑动的时候,他是保持不动的,可以理解为Excel中的表头,分析完毕。接着上代码。看下MainActivity长什么样

public class MainActivity extends AppCompatActivity {    // 界面上的控件    PRivate ListView mListView;    private MyListAdapter mAdapter;    private LinearLayout mTitleLayout ;    // 相关的数据    private List<ItemBean> dataList = new ArrayList<>(); // 测试实体类的集合    private ItemBean bean; // 测试实体类,模拟一个座位,有头像和姓名,以及座位号    private List<String> idList = new ArrayList<>(); // 为了大家便于理解,存放票面号    private static final int COLUMN_NUM = 10;  // 列数    private static final int ROW_NUM = 10; // 行数    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        mListView = (ListView) findViewById(R.id.mListView);        mTitleLayout = (LinearLayout) findViewById(R.id.titleLayout);        // 首先填充头部的标题布局        for (int i = 0; i < COLUMN_NUM; i++) {            View titleView = LayoutInflater.from(this).inflate(R.layout.item_text,null);            TextView title = (TextView) titleView.findViewById(R.id.itemTitleTv);            title.setText("标题"+i);            // 直接往LinearLayout中填充子元素,设置该子元素的宽高和宽所占的比重            mTitleLayout.addView(titleView,new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.MATCH_PARENT, 1.0f));        }        // 准备数据,这里仅仅准备票面的座位号,相当于准备票        for (int i = 1; i <= COLUMN_NUM; i++) {            for (int j = 1; j <= ROW_NUM; j++){                idList.add(i+"-"+j);            }        }        // 下面把刚刚准备好的一批票发放到每个人的手中        for (int i = 0; i < idList.size(); i++) {            bean = new ItemBean();            bean.setId(idList.get(i)); // 给这位同学发了一张票了            bean.setPictureName("同学" + i);            bean.setPictureResId(R.mipmap.ic_launcher); // 这位同学的长相            dataList.add(bean); // 添加到数据集合        }        // 设置适配器        mAdapter = new MyListAdapter(this, dataList, COLUMN_NUM );        mListView.setAdapter(mAdapter);    }}
代码注释也很清楚了,我就不再啰嗦了,有什么不明白的地方大家可以跟我留言,反正我也不会解答大笑得意。这里补充一下代码中几个xml布局的写法。

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"    android:padding="5dp">    <TextView        android:id="@+id/itemTitleTv"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:gravity="center"        android:textSize="18sp"        android:text="--标题--" /></LinearLayout>
这个就是标题的长相,也就是上图中标红的部分R.layout.item_text的写法。

下面看下适配器Adapter是怎么写的,

public class MyListAdapter extends BaseAdapter {    private Context mContext ;    private List<ItemBean> mDataLists ;    private int mColumnNum = 0 ;    public MyListAdapter() {    }    /**     *  构造函数     * @param mContext     * @param mDataLists     */    public MyListAdapter(Context mContext, List<ItemBean> mDataLists , int columnNum ) {        this.mContext = mContext;        this.mDataLists = mDataLists;        this.mColumnNum = columnNum ;    }    @Override    public int getCount() {        return mDataLists.size();    }    @Override    public ItemBean getItem(int i) {        return mDataLists.get(i);    }    @Override    public long getItemId(int i) {        return i;    }    @Override    public View getView(int position, View view, ViewGroup parent) {        view = LayoutInflater.from(mContext).inflate(R.layout.list_row_layout,null);        LinearLayout row = (LinearLayout) view.findViewById(R.id.listViewRow);  // 行布局        if(row != null) row.removeAllViews(); // 清空行        for (int i = 0; i < mColumnNum ; i++) {            View itemView = LayoutInflater.from(mContext).inflate(R.layout.item,null);            TextView itemNameTv = (TextView) itemView.findViewById(R.id.itemNameTv);            TextView itemLocationTv = (TextView) itemView.findViewById(R.id.itemLocationTv);            ItemBean itemBean = getLocationBean(position+1 , i+1); // 获取对应的实体类            if(itemBean != null){                itemNameTv.setText(itemBean.getPictureName());                itemLocationTv.setText(itemBean.getId());                // 将每个元素添加到行布局中去                row.addView(itemView, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.MATCH_PARENT, 1.0f));            }        }        return view;  // 返回加载好了内容的行布局    }    /***     *  根据座位号获取对应的元素     * @param row     * @param column     * @return     */    private ItemBean getLocationBean(int row , int column){        String index = column+"-"+row; // 生成索引,对比索引找到对应的学生        for (int i = 0; i < this.getCount(); i++) {            if(this.getItem(i).getId().equals(index))                return this.getItem(i) ;        }        return null ;    }}

下面摘出来的一段代码就是定位用的,在电影院里,就是凭借着票面上的xx排xx列找到自己的座位的,这里也是一样的原理

    private ItemBean getLocationBean(int row , int column){        String index = column+"-"+row; // 生成索引,对比索引找到对应的学生        for (int i = 0; i < this.getCount(); i++) {            if(this.getItem(i).getId().equals(index))                return this.getItem(i) ;        }        return null ;    }

这个Adapter中也有两个布局XML文件,主要是不想手写,其实纯粹可以手写,我习惯用LayoutInflater加载XML布局来实现的,这两个布局XML也贴出来给大家。

R.layout.list_row_layout: 这个是每行的布局,作为父容器来使用

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@+id/listViewRow"    android:orientation="horizontal"    android:layout_width="match_parent"    android:layout_height="match_parent"/>

R.layout.item:   就是每个位子上的布局

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    android:layout_width="match_parent"    android:gravity="center"    android:padding="16dp"    android:layout_height="match_parent">    <ImageView        android:layout_width="60dp"        android:layout_height="60dp"        app:srcCompat="@mipmap/ic_launcher"        android:layout_centerInParent="true"        android:id="@+id/itemImageView" />    <TextView        android:text="名称"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_below="@+id/itemImageView"        android:layout_centerHorizontal="true"        android:layout_marginTop="10dp"        android:id="@+id/itemNameTv" />    <TextView        android:text="坐标"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_below="@+id/itemNameTv"        android:layout_alignLeft="@+id/itemNameTv"        android:layout_alignStart="@+id/itemNameTv"        android:layout_centerHorizontal="true"        android:layout_marginTop="6dp"        android:id="@+id/itemLocationTv" /></RelativeLayout>

文末的福利放送:你也想制作文中的GIF图吗,推荐你一款软件LICEcap,这是地址:http://www.cockos.com/licecap/

源代码地址(下载不要分,拿走不谢):

Git仓库:https://github.com/1989Jiangtao/HorizontalScrollviewDemo

CSDN:http://download.csdn.net/detail/u010898329/9751237


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表