您的位置:首页 > 其它

自定义ViewGroup实现换行

2016-08-20 12:59 323 查看
在做搜索页面的时候,往往会有热词推荐,热词推荐的表现形式一般分为两种,一种是表格的形式,这种通过GridView很容易实现,还有另外一种,如下图所示:



这种布局方式,每一行容纳的View数量是不固定的,当超过屏幕宽度时会自动换行。其实要实现起来也很简单,自定义ViewGroup,重写onLayout方法,通过计算子View所占据的空间,重新布局。

实现代码如下:

public class AutoBreakViewGroup extends ViewGroup {
private int mScreenWidth;
private int mHorizontalSpacing;
private int mVerticalSpacing;

public AutoBreakViewGroup(Context context) {
super(context);
init();
}

public AutoBreakViewGroup(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}

public void setSpacing(int horizontalSpacing, int verticalSpacing) {
mHorizontalSpacing = horizontalSpacing;
mVerticalSpacing = verticalSpacing;
}

private void init() {
DisplayMetrics dm = getResources().getDisplayMetrics();
mScreenWidth = dm.widthPixels;
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
measureChildren(widthMeasureSpec, heightMeasureSpec);
setMeasuredDimension(widthSize, heightSize);
}

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int mTotalHeight = 0;
int mTotalWidth = 0;
int mTempHeight = 0;
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View childView = getChildAt(i);
int measureHeight = childView.getMeasuredHeight();
int measuredWidth = childView.getMeasuredWidth();
mTempHeight = (measureHeight > mTempHeight) ? measureHeight : mTempHeight;
if ((measuredWidth + mTotalWidth + mHorizontalSpacing) > mScreenWidth) {
mTotalWidth = 0;
mTotalHeight += (mTempHeight + mVerticalSpacing);
mTempHeight = 0;
}
childView.layout(mTotalWidth + mHorizontalSpacing, mTotalHeight, measuredWidth + mTotalWidth + mHorizontalSpacing, mTotalHeight + measureHeight);
mTotalWidth += (measuredWidth + mHorizontalSpacing);
}
}
}

代码很简单,其关键是left,top代表View左上角坐标,right,bottom代表View右下角坐标,通过简单的数学计算,就能够准确算出每个View的坐标位置。

xml文件如下:

<?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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.stefanli.drawdemo.MainActivity">
<com.stefanli.drawdemo.AutoBreakViewGroup
android:id="@+id/autoBreakViewGroup"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"/>
</RelativeLayout>

Activity代码如下:

public class MainActivity extends AppCompatActivity {
private ArrayList<String> mData = new ArrayList<>();
private Context mContext;
private AutoBreakViewGroup autoBreakViewGroup;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mContext = this;
setContentView(R.layout.activity_main);
autoBreakViewGroup = (AutoBreakViewGroup) findViewById(R.id.autoBreakViewGroup);
autoBreakViewGroup.setSpacing(20, 20);
initView();
}

private void initView() {
mData.add("隔帘花影");
mData.add("国色天香");
mData.add("快穿");
mData.add("空空幻");
mData.add("总裁");
mData.add("诛仙");
mData.add("旋风少女");
mData.add("耳根");
mData.add("系统");

for (int i = 0; i < mData.size(); i++) {
TextView textView = new TextView(mContext);
textView.setText(mData.get(i));
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
textView.setTextColor(Color.BLACK);
textView.setLayoutParams(new
LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
textView.setBackgroundResource(R.drawable.item_bg);
textView.setPadding(20, 10, 20, 10);
textView.setGravity(Gravity.CENTER);
autoBreakViewGroup.addView(textView);
}
}
}

大功告成,实现效果如下:



文/stefanli(简书作者)

原文链接:http://www.jianshu.com/p/47c39b9e37ee

著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: