在平时开发中柱状形状偶尔会有项目需求,由于又一次开发需要,去找开源的组件都不好用,要不调用很不方便,要不它们类库太笨重,下面介绍一个轻巧方便控件,原理就是用View 重新绘画一个柱状图形控件,并适配所有屏幕。
该项目地址位于:https://github.com/apple317/displayview。
demo实现后效果图如上,后续补上
1. 导入DisplayView(简称SDK)
下载最新版sdk的zip包,解压将其中的download释放到本地目录,Eclipse用户右键您的工程根目录,选择Properties -> Java Build Path -> Libraries, 然后点击 Add External JARs... 选择指向download 的路径,点击OK,即导入成功。
下载最新版SDK的zip包,将其中的libs 文件夹合并到本地工程libs子目录下
Eclipse用户右键工程根目录,选择Properties -> Java Build Path -> Libraries,然后点击Add External JARs... 选择指向jar的路径,点击OK,即导入成功。
注意。
2.代码接入详解使用说明:
在下载代码后,里面有参考布局layout_grid.xml,具体代码如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@drawable/stripe_repeat"
android:orientation="vertical" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="64dip"
android:gravity="center" >
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center">
</ImageView>
<TextView
style="@style/TextAppearance.Shadow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dip"
android:gravity="center"
android:text="启动菜单"
android:textColor="#ffffff"
android:textSize="28dip" />
</LinearLayout>
<ScrollView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_marginBottom="20dip"
android:layout_marginRight="20dip"
android:layout_weight="1"
android:orientation="vertical" >
<!-- 调用自定义View组件 -->
<com.apple.disview.GridLayoutBottom
android:id="@+id/layout_button"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center_horizontal"
android:gravity="center_horizontal"
android:paddingLeft="20dip"
android:paddingTop="20dip" >
<!-- 添加一个子View视图-->
<Button
android:id="@+id/Install"
style="@style/Widget.Button.Long"
android:text="@string/install"
android:textSize="20sp" >
</Button>
<ToggleButton
android:id="@+id/toggleButton1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="ToggleButton"
android:textOff="跳过\nBootMenu\n启动"
android:textOn="通过\nBootMenu\n启动"
android:textSize="15sp" >
</ToggleButton>
<Button
android:id="@+id/Reboot2bm"
style="@style/Widget.Button.Long"
android:text="@string/boot_mode"
android:textSize="15sp" >
</Button>
<Button
android:id="@+id/Reboot2rv"
style="@style/Widget.Button.Long"
android:text="@string/reboot2rv"
android:textSize="15sp" >
</Button>
<Button
android:id="@+id/Reboot"
style="@style/Widget.Button.Long"
android:text="@string/reboot"
android:textSize="20sp" >
</Button>
<Button
android:id="@+id/QReboot"
style="@style/Widget.Button.Long"
android:text="@string/killall"
android:textSize="20sp" >
</Button>
</com.apple.disview.GridLayoutBottom>
</ScrollView>
</LinearLayout>
3.核心自定义ViewGroup实现说明:
在ViewGroup实现了自身View长度绘画,定义每个子视图长度和位置设置,具体代码如下:
public class GridLayoutBottom extends ViewGroup {
static private final String TAG = "ButtonGridLayout";
static private final int COLUMNS_LAND = 4;
static private final int COLUMNS_PORT = 3;
private int COLUMNS, ROWS, NUM_CHILDREN;
private View[] mButtons;
// This what the fields represent (height is similar):
// PL: mPaddingLeft
// BW: mButtonWidth
// PR: mPaddingRight
//
// mWidthInc
// <-------------------->
// PL BW PR
// <----><--------><---->
// --------
// | |
// | button |
// | |
// --------
//
// We assume mPaddingLeft == mPaddingRight == 1/2 padding between
// buttons.
//
// mWidth == COLUMNS x mWidthInc
// Width and height of a button
private int mButtonWidth;
private int mButtonHeight;
// Width and height of a button + padding.
private int mWidthInc;
private int mHeightInc;
// Height of the dialpad. Used to align it at the bottom of the
// view.
private int mWidth;
private int mHeight;
/**
* Cache the buttons in a member array for faster access. Compute the
* measurements for the width/height of buttons. The inflate sequence is
* called right after the constructor and before the measure/layout phase.
*/
public GridLayoutBottom(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
public GridLayoutBottom(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
}
public GridLayoutBottom(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
// COLUMNS = mContext.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT ? COLUMNS_PORT
// : COLUMNS_LAND;
COLUMNS=3;
if (mButtons == null) {
NUM_CHILDREN = getChildCount();
mButtons = new View[NUM_CHILDREN];
// 得到行数
ROWS = NUM_CHILDREN / COLUMNS
+ (NUM_CHILDREN % COLUMNS > 0 ? 1 : 0);
}
final View[] buttons = mButtons;
for (int i = 0; i < NUM_CHILDREN; i++) {
buttons[i] = getChildAt(i);
// Measure the button to get initialized.
buttons[i]
.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
}
// Cache the measurements.
final View child = buttons[0];
mButtonWidth = child.getMeasuredWidth();
mButtonHeight = child.getMeasuredHeight();
mWidthInc = mButtonWidth + 10 + 10;
mHeightInc = mButtonHeight + 10 + 10;
mWidth = COLUMNS * mWidthInc;
mHeight = ROWS * mHeightInc;
}
@Override
protected void onLayout(boolean changed, int left, int top, int right,
int bottom) {
final View[] buttons = mButtons;
final View parent = (View) getParent();// fill parent mode
final int height = parent.getHeight();
final int width = parent.getWidth();
final int paddingLeft = 10;
int buttonWidth;
int buttonHeight;
int widthInc;
int heightInc;
//mPaddingTop
if (ROWS * mButtonHeight + (ROWS - 1) * 10< height) {
//mPaddingLeft
buttonWidth = (width - 10 * (COLUMNS - 1)) / COLUMNS;
//mPaddingTop
buttonHeight = (height - 10 * (ROWS - 1)) / ROWS;
widthInc = width / COLUMNS;
heightInc = height / ROWS;
mWidth = width;
mHeight = height;
} else {
buttonWidth = mButtonWidth;
buttonHeight = mButtonHeight;
widthInc = mWidthInc;
heightInc = mHeightInc;
}
int i = 0;
// The last row is bottom aligned.
//int y = (bottom - top) - mHeight + mPaddingTop;
int y = (bottom - top) - mHeight + 10;
for (int row = 0; row < ROWS; row++) {
int x = paddingLeft;
for (int col = 0; col < COLUMNS && i < NUM_CHILDREN; col++) {
View button = buttons[i];
button.layout(x, y, x + buttonWidth, y + buttonHeight);
/*
* if(button instanceof Button){ Button btn = (Button)button;
* int size = buttonHeight/6; btn.setTextSize(size > 32 ? 32 :
* size); btn.setGravity(Gravity.CENTER); }
*/
x += widthInc;
i++;
}
y += heightInc;
}
}
/**
* This method is called twice in practice. The first time both with and
* height are constraint by AT_MOST. The second time, the width is still
* AT_MOST and the height is EXACTLY. Either way the full width/height
* should be in mWidth and mHeight and we use 'resolveSize' to do the right
* thing.
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
final int width = resolveSize(mWidth, widthMeasureSpec);
final int height = resolveSize(mHeight, heightMeasureSpec);
setMeasuredDimension(width, height);
}
}