[android] 瀑布流布局——分页加载(详细代码)

效果是这个样的:

布局思路:

最外层父窗体是一个RelativeLayout(图里没画出来),从内层开始。

黑色:自定义ScrollView

红色:LinearLayout,为了盛放内层三个布局,orientation为水平。

绿色:三个LinearLayout,用来实现散列的瀑布流效果。orientation为垂直。

间隙:实际不存在,这里只是为了能看清结构。

布局代码:

    <com.example.stream.SV
        android:id="@+id/sv"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" >

        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal" >

            <LinearLayout
                android:id="@+id/ll1"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:orientation="vertical" >
            </LinearLayout>

            <LinearLayout
                android:id="@+id/ll2"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:orientation="vertical" >
            </LinearLayout>

            <LinearLayout
                android:id="@+id/ll3"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:orientation="vertical" >
            </LinearLayout>
        </LinearLayout>
    </com.example.stream.SV>

自定义ScrollView

用的是自定义ScrollView,因为原生的ScrollView没有滑动监听事件。用到上一篇博客所讲的自定义View,重写onTouchEvent()方法。设置回调接口,用来分页加载。

<span style="font-size:18px;">public class SV extends ScrollView{
	private OnScrollListener listener;
	public SV(Context context) {
		super(context);
	}
	public SV(Context context, AttributeSet attrs) {
		super(context, attrs);
	}
<span style="color:#ff0000;">	//传进来一个接口对象
	public interface OnScrollListener{
		void loadMore();
	}</span>

<span style="color:#ff0000;">	//设置滑动监听
	public void setOnScrollListener(OnScrollListener listener){
		this.listener = listener;
	}</span>

	//手指对屏幕的触摸事件---》监听是否滑到底
	@Override
	public boolean onTouchEvent(MotionEvent ev) {
		View childView = getChildAt(0);
		//获取测量高度(总高度)
		int measuredHeight = childView.getMeasuredHeight();
		//获取画出屏幕高度
		int scrollY = getScrollY();
		//获取可视区域
		int height = getHeight();
<span style="white-space:pre">		</span>//判断位置
		if(measuredHeight==scrollY+height){
			Toast.makeText(getContext(), "到底了!", 0).show();
			listener.loadMore();
		}
		return super.onTouchEvent(ev);
	}
}</span>

通过这样计算来判断ScrollView是否滑到了底部,是否可以继续请求数据。

getHeight()+getScrollY()==getMeasureHeight();

MainActivity

注释已经很清楚了

<span style="font-size:18px;">public class MainActivity extends Activity {
	private LinearLayout ll1, ll2, ll3;
	// 每一个ImageView的宽度,是屏幕宽度的1/3
	private int imgvWidth;
	// 每次加载多少个
	private int pageSize = 15;
	//加载次数,每加载一次,pageIndex++
	private int pageIndex = 0;

	private String[] imgName;
	//布局有三个,添加到数组里,以便更新UI的时候使用。
	private LinearLayout lls[] = new LinearLayout[3];

	// 自定义ScrollView SV
	private SV sv;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		init();
	}

	private void init() {
		sv = (SV) findViewById(R.id.sv);
		// 用来盛放屏幕信息
		DisplayMetrics outMetrics = new DisplayMetrics();
		getWindowManager().getDefaultDisplay().getMetrics(outMetrics);
		//设置每个LinearLayout的宽度为整个屏幕的1/3
		imgvWidth = outMetrics.widthPixels / 3;
		ll1 = (LinearLayout) findViewById(R.id.ll1);
		ll2 = (LinearLayout) findViewById(R.id.ll2);
		ll3 = (LinearLayout) findViewById(R.id.ll3);
		lls[0] = ll1;
		lls[1] = ll2;
		lls[2] = ll3;

		try {
			//获取所有文件名
			imgName = getAssets().list("imgs");
		} catch (IOException e) {
			e.printStackTrace();
		}
		// 第一次加载图片
		loadImage();
		//设置scrollView的滚动监听
		sv.setOnScrollListener(new OnScrollListener() {
			@Override
			public void loadMore() {
				if (pageIndex * pageSize >= imgName.length) {
					Toast.makeText(getApplicationContext(), "数据加载完成", 0).show();
				} else {
					loadImage();
				}
			}
		});
	}

	// 进行图片加载
	private void loadImage() {
		//如果加载的数量比所有文件个数少,每次加载15张
		for (int i = pageIndex * pageSize; i < pageIndex * pageSize + pageSize
				&& i < imgName.length; i++) {
			// 加载图片,实例化一个ImageView
			ImageView imgv = new ImageView(MainActivity.this);
			// 宽度是屏幕的1/3
			LayoutParams lp = new LayoutParams(imgvWidth,
					LayoutParams.WRAP_CONTENT);
			imgv.setLayoutParams(lp);
			// 加载图片资源
			LoadImageFromAssets.load(MainActivity.this, imgName[i], imgv);
			//每次往不同的LinearLayout放一个带有图片的ImageView
			lls[i % 3].addView(imgv);
		}
		pageIndex++;
	}
}</span>

从assets加载数据

<span style="font-size:18px;">public class LoadImageFromAssets {
	public static void load(final Activity activity,final String name,final ImageView iv){
		new Thread(){
			public void run(){
				try {
					//从assets/imgs里获取图片资源,传入图片名字
					InputStream stream = activity.getAssets().open("imgs/"+name);
					final Bitmap bitmap = BitmapFactory.decodeStream(stream);
					//主线程更新UI
					activity.runOnUiThread(new Runnable(){
						public void run(){
							//获取图片宽高
							int bitH = bitmap.getHeight();
							int bitW = bitmap.getWidth();
							//获取LayoutParams设置宽高,使图片填充整个ImageView
							LayoutParams lp = (LayoutParams) iv.getLayoutParams();
							/**
							 * 图片的宽高比等于ImageView的宽高比,因为ImageView宽度已经确定(1/3父窗体),通过计算
							 * 得到ImageView的高度
							 */
							lp.height = bitH*lp.width/bitW;
							//将参数设置到ImageView
							iv.setLayoutParams(lp);
							iv.setImageBitmap(bitmap);
						}
					});
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}.start();
	}
}</span>

文笔不好,好多东西只有在代码里注释才讲的出来,博客我会一直坚持,整理的过程中,也在思考如何写好博客。我在一直努力。

时间: 2024-08-26 00:28:52

[android] 瀑布流布局——分页加载(详细代码)的相关文章

Android中的分页加载

//----------------------MainActivity中--------------------------------------------------- package com.example.fenye; import java.util.ArrayList;import java.util.List; import android.os.Bundle;import android.app.Activity;import android.view.Menu;import

Android中ListView分页加载数据-转

Android应用开发中,采用ListView组件来展示数据是很常用的功能,当一个应用要展现很多的数据时,一般情况下都不会把所有的数据一次就展示出来,而是通过分页的形式来展示数据,个人觉得这样会有更好的用户体验.因此,很多应用都是采用分批次加载的形式来获取用户所需的数据.例如:微博客户端可能会在用户滑动至列表底端时自动加载下一页数据,也可能在底部放置一个"查看更多"按钮,用户点击后,加载下一页数据. 下面通过一个Demo来展示ListView功能如何实现:该Demo通过在ListVie

Android中ListView分页加载数据

熟悉Android的朋友们都知道,不管是微博客户端还是新闻客户端,都离不开列表组件,可以说列表组件是Android数据展现方面最重要的组件,我们今天就要讲一讲列表组件ListView加载数据的相关内容.通常来说,一个应用在展现大量数据时,不会将全部的可用数据都呈现给用户,因为这不管对于服务端还是客户端来说都是不小的压力,因此,很多应用都是采用分批次加载的形式来获取用户所需的数据.比如:微博客户端可能会在用户滑动至列表底端时自动加载下一页数据,也可能在底部放置一个“加载更多”按钮,用户点击后,加载

小程序中分页加载问题

别的不说,直接贴分页加载的代码,看注释就好 pasting //index.js const app = getApp() //分装的require 函数,http.js见本人随笔"解决小程序分装的require问题" var http = require('../../../service/http.js'); Page({ data: { newsBulletin: [], page:1, pageSize:8, hasMoreData: true, }, /** * 生命周期函数

iOS 高效的分页加载(TableView、CollectionView)

一.tableview的分页加载的代码对比 没有优化之前的代码如下 [strongSelf.tableView.mj_footer endRefreshing]: [strongSelf.articleArr addObjectsFromArray:feedList]; [strongSelf.tableView reloadData]; 优化之后的代码 NSMutableArray *indexPaths = [NSMutableArray array]; [feedList enumerat

基于Android官方Paging Library的RecyclerView分页加载框架

基于Android官方Paging Library的RecyclerView分页加载框架 我之前写了一篇RecyclerView分页加载机制的文章,是基于Android官方的AsyncListUtil实现的,详情见附录文章1.现在再介绍一种RecyclerView分页加载框架:Android Paging Library.Android Paging Library是Android官方support-v7支持包中专门做的分页框架,详细文档见谷歌官方文档附录2页面.我写这篇文章时候Paging L

Android ListView分页加载(服务端+android端)Demo

Android ListView分页加载功能 在实际开发中经常用到,是每个开发者必须掌握的内容,本Demo给出了服务端+Android端的两者的代码,并成功通过了测试. 服务端使用MyEclipse,Android端使用Eclipse. 实现效果图: 服务端一共100条数据,共分四页,每页有25条数据. 源代码: 服务端: 需要导入图中这几个jar包. 在运行Android端代码前,需要开启服务端: 下面先给出服务端的代码: 类EmpDataSource: package com.android

android UI进阶之实现listview的分页加载

 分享了下拉刷新,这是一个用户体验非常好的操作方式.新浪微薄就是使用这种方式的典型. 还有个问题,当用户从网络上读取微薄的时候,如果一下子全部加载用户未读的微薄这将耗费比较长的时间,造成不好的用户体验,同时一屏的内容也不足以显示如此多的内容.这时候,我们就需要用到另一个功能,那就是listview的分页了.通过分页分次加载数据,用户看多少就去加载多少. 通常这也分为两种方式,一种是设置一个按钮,用户点击即加载.另一种是当用户滑动到底部时自动加载.今天我就和大家分享一下这个功能的实现. 首先,

Android开发之ListView利用OnScrollListener实现分页加载数据

上篇博文和大家分享了下拉刷新,这是一个用户体验非常好的操作方式.新浪微薄就是使用这种方式的典型. 还有个问题,当用户从网络上读取微薄的时候,如果一下子全部加载用户未读的微薄这将耗费比较长的时间,造成不好的用户体验,同时一屏的内容也不足以显示如此多的内容.这时候,我们就需要用到另一个功能,那就是listview的分页了.通过分页分次加载数据,用户看多少就去加载多少. 通常这也分为两种方式,一种是设置一个按钮,用户点击即加载.另一种是当用户滑动到底部时自动加载.今天我就和大家分享一下这个功能的实现.