Android流式布局的简单实现
来源:互联网 发布:linux 下载速度 编辑:程序博客网 时间:2024/06/10 05:46
这就是我们要实现的流式布局。
难点就在于如何控制子View的布局,动态的判断是否将子View放置在下一行。
很明显,我们需要写一个类来继承ViewGroup。
package com.example.demo.autolinefeedlayout;import android.content.Context;import android.content.res.TypedArray;import android.util.AttributeSet;import android.util.Log;import android.view.View;import android.view.ViewGroup;import android.widget.Button;public class AutoLineFeedLayout extends ViewGroup { private static final boolean DEBUG = true; private static final String TAG = "AutoLineFeedLayout"; private int paddingLeft = 0; private int paddingRight = 0; private int paddingTop = 0; private int paddingBottom = 0; private int verticalSpacing = 0; private int horizontalSpacing = 0; private int mWidth; public AutoLineFeedLayout(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(attrs); } public AutoLineFeedLayout(Context context, AttributeSet attrs) { this(context, attrs, 0); } public AutoLineFeedLayout(Context context) { this(context, null); } /** * 获取布局文件中的一些值 * @param attrs */ private void init(AttributeSet attrs) { TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.AutoLineFeedLayout); horizontalSpacing = (int) typedArray.getDimension( R.styleable.AutoLineFeedLayout_horizontalSpacing, 0); paddingLeft = (int) typedArray.getDimension( R.styleable.AutoLineFeedLayout_paddingLeft, 0); paddingTop = (int) typedArray.getDimension( R.styleable.AutoLineFeedLayout_paddingTop, 0); paddingBottom = (int) typedArray.getDimension( R.styleable.AutoLineFeedLayout_paddingBottom, 0); verticalSpacing = (int) typedArray.getDimension( R.styleable.AutoLineFeedLayout_verticalSpacing, 0); paddingRight = (int) typedArray.getDimension( R.styleable.AutoLineFeedLayout_paddingRight, 0); typedArray.recycle(); } private void log(String string) { if (DEBUG) { Log.i(TAG, string); } } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { log("l=" + l + " t=" + t + " r=" + r + " b=" + b); int count = getChildCount(); mWidth = getWidth(); log("mWidth=" + mWidth); //第一个子View开始放置的距离父控件左边的距离 int startOffsetX = paddingLeft; //第一个子View开始放置的距离父控件上边的距离 int startOffsetY=0+paddingTop; int preEndsetX; **for (int i = 0; i < count; i++) { View childView = getChildAt(i); childView.measure(0,0); //子View的宽度 int w = childView.getMeasuredWidth(); //子View的高度 int h = childView.getMeasuredHeight(); log("w=" + w + " h=" + h); //子View的右端距离父控件的左边的距离 preEndsetX=startOffsetX+w; //如果距离大于宽度-右间距的距离,则该子View应该在新的一行 if (preEndsetX > mWidth - paddingRight) { if (startOffsetX > paddingLeft) { //设置新起一行的子View到父控件的距离 startOffsetX=paddingLeft; startOffsetY = h + startOffsetY +horizontalSpacing; } } childView.layout(startOffsetX, startOffsetY, startOffsetX+ w, startOffsetY + h); //设置下一个子view开始放置的距离父控件左边的距离 startOffsetX=startOffsetX+w+verticalSpacing; }** } public void setOnItemClickListener(final onItemClickListener onItemClickListener) { int count=getChildCount(); for (int i = 0; i < count; i++) { final View view=getChildAt(i); Button btn = (Button) view.findViewById(R.id.btn); btn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { if (onItemClickListener != null) { v.setTag(((Button)v).getText()); onItemClickListener.setOnItemClickListener(v); } } }); } } public interface onItemClickListener{ void setOnItemClickListener(View v); }}
MainActivity的代码:
package com.example.demo.autolinefeedlayout;import android.app.Activity;import android.os.Bundle;import android.view.LayoutInflater;import android.view.View;import android.widget.Button;import android.widget.Toast;import java.util.Random;public class MainActivity extends Activity { private AutoLineFeedLayout layout; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Random random = new Random(); layout = (AutoLineFeedLayout) findViewById(R.id.al); View view; for (int i = 0; i < 20; i++) { view = LayoutInflater.from(MainActivity.this).inflate(R.layout.button, null); Button button = (Button) view.findViewById(R.id.btn); if ((i & 1) == 0) button.setText("按钮" + random.nextInt(1000)+random.nextInt(1000)); else button.setText(random.nextInt(10) + "按钮"); layout.addView(view, i); } layout.setOnItemClickListener(new AutoLineFeedLayout.onItemClickListener() { @Override public void setOnItemClickListener(View view) { Toast.makeText(getApplicationContext(), (String) view.getTag(), Toast.LENGTH_SHORT).show(); } }); }}
自定义该控件的属性:
<?xml version="1.0" encoding="utf-8"?><resources> <declare-styleable name="AutoLineFeedLayout"> <attr name="paddingLeft" format="reference|dimension" /> <attr name="paddingRight" format="reference|dimension" /> <attr name="paddingTop" format="reference|dimension" /> <attr name="paddingBottom" format="reference|dimension" /> <attr name="verticalSpacing" format="reference|dimension" /> <attr name="horizontalSpacing" format="reference|dimension" /> </declare-styleable></resources>
activity_main.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" tools:context=".MainActivity"> <com.example.demo.autolinefeedlayout.AutoLineFeedLayout android:id="@+id/al" android:layout_width="match_parent" android:layout_height="match_parent" app:paddingLeft="5dp" app:paddingRight="5dp" app:paddingTop="20dp" app:paddingBottom="20dp" app:verticalSpacing="10dp" app:horizontalSpacing="10dp" /></LinearLayout>
子View的布局文件:
<?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"><Button android:id="@+id/btn" android:layout_width="wrap_content" android:layout_height="wrap_content" /></LinearLayout>
Demo下载:
Android流式布局Demo
0 0
- Android流式布局的简单实现
- Android流式布局的简单实现
- android 流式布局简单实现
- Android 简单实现流式布局
- Android开发学习之卡片式布局的简单实现
- Android开发学习之卡片式布局的简单实现
- Android卡片式布局的简单实现方法
- Android之路-简单布局的实现
- Android 简单 相对布局的实现;
- Android流式布局的实现原理
- Java实现一个简单的计算器(流式布局)
- 可能是史上最简单的Android Tab布局的实现
- Android流式布局实现
- Android流式布局实现
- Android流式布局实现
- Android流式布局实现
- 实现Android流式布局
- 简单的几行小代码,实现Android程序布局替换。
- 19.5 Partition Selection 分区查询
- C、C++多组输入方法
- Spring 学习笔记(五)——MVC
- 使用Zxing生成二维码,以及保存到sdcard,图片变黑的问题
- windows服务创建工具srvany.exe介绍
- Android流式布局的简单实现
- Extjs中 requires uses singleton 的区别
- unity3d 实现简单的水下相机效果脚本代码
- 互联网产品经理应该具备的技能(需求篇)
- Override和Overload区别,Overloaded的方法是否可以改变返回值的类型?
- UDP服务器和客户端交互
- 安卓学习—Android应用程序架构
- sql使用exists
- org.hibernate.NonUniqueObjectException