自定义ViewGroup实现换行

2017-01-14 10:05:47来源:http://www.jianshu.com/p/47c39b9e37ee作者:stefanli人点击

在做搜索页面的时候,往往会有热词推荐,热词推荐的表现形式一般分为两种,一种是表格的形式,这种通过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);
}
}
}

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






最新文章

123

最新摄影

微信扫一扫

第七城市微信公众平台