GridLayout 网格布局,在开发中并不是很常用,今天偶然用了一下发现并不是太会用,所以作此笔记以避免后面再次踏坑。
GridLayout 兼容包:compile 'com.android.support:gridlayout-v7:23.+'
-
先看布局大图:
image.png - 上图是对GridLayout做了小修改后动态添加的Item。
xml布局
- 此空间为重写GridLayout的自定义空间。
<com.shTelecom.view.views.ActionsView
android:id="@+id/action_msg_listLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:rowCount="3"
android:columnCount="4"
android:orientation="horizontal"
android:focusable="true">
</com.shTelecom.view.views.ActionsView>
- 要做到每个item平分GridLayout在xml布局中可以对
android:layout_columnWeight="1"即可。
或代码中在GridLayout 的onLayout中对View设置最小宽度为
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
int count = getChildCount();
if (count > lastCount +1){
for (int i = lastCount; i < count; i++) {
getChildAt(i).setMinimumWidth(getWidth() / getColumnCount());
lastCount = i;
// Log.e("onLayout" ,"-------------- lastCount: " + lastCount);
}
}
}
-
常规操作:
image.png
<GridLayout
android:id="@+id/action_msg_listLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:rowCount="3"
android:columnCount="4"
android:orientation="horizontal"
android:focusable="true">
<Button
android:layout_columnSpan="2"
android:layout_columnWeight="1"
android:text="1"/>
<Button
android:text="2"/>
<Button
android:text="3"/>
<Button
android:text="4"/>
<Button
android:text="5"/>
</GridLayout>
View属性:
- android:alignmentMode
alignMargins,使视图的外边界之间进行校准。取值:
alignBounds – 对齐子视图边界。
alignMargins – 对齐子视距内容。 - android:columnCount
GridLayout的最大列数 - android:rowCount
GridLayout的最大行数 - android:columnOrderPreserved
true,使列边界显示的顺序和列索引的顺序相同。默认是true。 - android:orientation
GridLayout中子元素的布局方向。取值:
horizontal – 水平布局。
vertical – 竖直布局。 - android:rowOrderPreserved
true,使行边界显示的顺序和行索引的顺序相同。默认是true。 - android:useDefaultMargins
ture,没有指定视图的布局参数时,GridLayout使用默认的边距。默认值是false。
子View属性
- android:layout_column
显示该子控件的列,例如android:layout_column=”0”,表示当前子控件显示在第1列,android:layout_column=”1”,表示当前子控件显示在第2列。 - android:layout_columnSpan
该控件所占的列数,例如android:layout_columnSpan=”2”,表示当前子控件占两列。 - android:layout_row
显示该子控件的行,例如android:layout_row=”0”,表示当前子控件显示在第1行,android:layout_row=”1”,表示当前子控件显示在第2行。 - android:layout_rowSpan
该控件所占的列数,例如android:layout_rowSpan=”2”,表示当前子控件占两行。 - android:layout_columnWeight (API21以上使用)
该控件的列权重,与android:layout_weight类似,例如有GridLayout上两列,都设置android:layout_columnWeight = “1”,则两列各占GridLayout宽度的一半 - android:layout_rowWeight (API21以上使用)
该控件的行权重,原理同android:layout_columnWeight。
//利用代码确定View的位置
GridLayout.LayoutParams params = new GridLayout.LayoutParams();
for(int i=1; i <= count; ++i){
//首先GridLayout行列,是从0开始计算的,所以我们第一个num应该在1,0的位置
//设置所在列的宽度和高度
params.width = minWidth;
//设置View在表格的什么位置。Spec用来设置View在表格的位置,View占几个单元格,且View在单元格的状态(是否占满单元格的行,或者占满单元格的列)
params.rowSpec = GridLayout.spec(i);//行的位置。
params.columnSpec = GridLayout.spec(0);//列的位置。
}
对比TableLayout,GridLayout的缺点和优点
优点:
- 能够横向、和纵向的合并单元格,TableLayout只能够纵向合并单元格
- 能够指定View该方法在那个格子里面,TableLayout却不能
- GridLayout可以设置是横向添加View还是纵向添加View。TableLayout只能横向添加
缺点: - 没有TableLayout 的行是行、列是列的点。
ActionsView 源码
public class ActionsView extends GridLayout implements View.OnClickListener{
private LayoutParams layoutParams;
private LinearLayout.LayoutParams layoutParams2;
private LayoutInflater inflater;
private OnClickItemListener onClickItemListener;
private int lastCount = 0;
private int width1 = 0;
private String name;
private int num;
private int icon;
public ActionsView(Context context) {
super(context ,null);
}
public ActionsView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
setOrientation(HORIZONTAL);
inflater = LayoutInflater.from(getContext());
layoutParams = new LayoutParams();
layoutParams2 = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT
,LinearLayout.LayoutParams.WRAP_CONTENT);
width1 = getMeasuredWidth();
}
public void addOnClickItemListener(OnClickItemListener onClickListener) {
this.onClickItemListener = onClickListener;
int size = getChildCount();
if (onClickItemListener != null && size > 0) {
for (int i = 0; i < size; i++) {
getChildAt(i).setOnClickListener(this);
}
}
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
int count = getChildCount();
if (count > lastCount +1){
for (int i = lastCount; i < count; i++) {
getChildAt(i).setMinimumWidth(getWidth() / getColumnCount());
lastCount = i;
// Log.e("onLayout" ,"-------------- lastCount: " + lastCount);
}
}
}
public void addItem(String name , @DrawableRes int icon , int num) {
this.name = name;
this.num = num;
this.icon = icon;
LinearLayout layoutp = new LinearLayout(getContext());
layoutp.setOrientation(LinearLayout.VERTICAL);
layoutp.setGravity(Gravity.CENTER);
layoutp.setMinimumWidth(width1 / getColumnCount());
MsgImageView msgView = new MsgImageView(getContext());
TextView nameView = new TextView(getContext());
msgView.setMsgNum(num);
msgView.setImageResource(icon);
nameView.setText(name);
msgView.setLayoutParams(layoutParams2);
nameView.setLayoutParams(layoutParams2);
layoutp.addView(msgView);
layoutp.addView(nameView);
layoutp.setTag(getChildCount());
if (onClickItemListener != null) {
layoutp.setOnClickListener(this);
}
addView(layoutp);
}
@Override
public void onClick(View view) {
if (this.onClickItemListener != null) {
onClickItemListener.onItem((Integer) view.getTag());
}
}
public interface OnClickItemListener {
void onItem(int position);
}
}
网友评论