[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>
文笔不好,好多东西只有在代码里注释才讲的出来,博客我会一直坚持,整理的过程中,也在思考如何写好博客。我在一直努力。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。