之前一直想做 一个android 开发手册,将知识分类整理,方便自己查找,最近开始动工了,其中首页我采用自定义一个菜单,给大家分享一下成果效果如图所示:边看图边理解;
1、效果说明
图一: 这里面这个布局是个GridView ,GridView中的每一项就是我定义的View:CompositeView;我们可以根据你要显示的菜单内容,来设置CompositeView,它有一个主标题,就是中间红色的文字,接着就是,他所显示的数据子标题蓝色的文字;页面效果是如此;
CompositeView 提供了一个事件,当你点击 子标题时,可以做相应的操作;效果看下图
图二:所示当点击 数据存储的子标题assert 文字变红,同时输出一句话,在这里大家呢,就可以自由发挥,做自己想做的事;
图三验证效果
图四验证效果跳转到另一页
2、思路讲解
CompositeView: 主要有两个难点,
1)绘制文字如何定位
根据传进来的子标题 ,绘制文字,我是绕着中心点向外发散 确定坐标点,每个子标题有个确定一个矩形范围;
2)如何确定当前点击的就是 子标题;
在外面定了每个子标题的矩形范围,当点击CompositeView时,获取位置判断是在哪个范围内,将对应范围内的标题、内容通过自定义的接口传出去;
##3、代码
package com.org.xiuer.androidlearningmanual.View;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import com.org.orglib.Math.ZPoint;
import com.org.xiuer.androidlearningmanual.R;
import com.org.xiuer.androidlearningmanual.model.AndroidTheory.Catalog;
import java.util.ArrayList;
import java.util.List;
/**
* Created by zhangxiu on 2017/1/9.
*/
public class CompositeView extends View {
public void setClick(OnItemClickListener click) {
this.click = click;
}
private OnItemClickListener click;
private List<Catalog>datas;
private int mWidth;
private int mHeight;
private String MainTitle;
private int FontSize;
private Rect mRect;
private Paint paint;
private List<SubTitle>subtitles=new ArrayList<>();
/**
* 每个目录的活动范围
*/
private List<ZPoint> points=new ArrayList<>();
public String getMainTitle() {
return MainTitle;
}
public void setMainTitle(String mainTitle) {
MainTitle = mainTitle;
invalidate();
}
public List<Catalog> getDatas() {
return datas;
}
public void setDatas(List<Catalog> datas) {
this.datas = datas;
invalidate();
}
public void setFontSize(int fontSize) {
FontSize = fontSize;
}
public void init(){
paint=new Paint();
paint.setAntiAlias(false);
mRect=new Rect();
}
public CompositeView(Context context) {
super(context);
init();
}
public CompositeView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public CompositeView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray array=context.getTheme().obtainStyledAttributes(attrs,
R.styleable.CompositeView,defStyleAttr,0);
for(int i=0;i<array.getIndexCount();i++) {
switch (array.getIndex(i)) {
case R.styleable.CompositeView_MainTitle:
MainTitle = array.getString(i);
break;
}
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width,height;
int widthMode=MeasureSpec.getMode(widthMeasureSpec);
int widthSize=MeasureSpec.getSize(widthMeasureSpec);
int heightMode=MeasureSpec.getMode(heightMeasureSpec);
int heightSize=MeasureSpec.getSize(heightMeasureSpec);
//充满父控件
if(widthMode==MeasureSpec.EXACTLY){
width=widthSize;
}else {
//自定义宽
width=mRect.width()+20;
}
if(heightMode==MeasureSpec.EXACTLY){
height=heightSize;
}else {
height=width;
}
mWidth=width;
mHeight=height;
setMeasuredDimension(width, height);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
paint.setColor(Color.GRAY);
paint.setStrokeWidth(10);
paint.setStyle(Paint.Style.STROKE);
canvas.drawRect(0,0,mWidth,mHeight,paint);
//中心圆圈
paint.setColor(Color.RED);
paint.setStrokeWidth(2);
paint.setStyle(Paint.Style.FILL);
float cx=mWidth/2;
float cy=mHeight/2;
float radius=mWidth/6;
paint.setAntiAlias(false);
paint.setTextAlign(Paint.Align.CENTER);
canvas.drawCircle(cx,cy,radius,paint);
paint.setTextSize(this.FontSize);
if(datas!=null){
double v= Math.PI*2/datas.size();
for(int i=1;i<=datas.size();i++){
float cx1=(float) Math.cos(v*i)*radius+cx;
float cy1=(float) Math.sin(v*i)*radius+cy;
float dx=(float) Math.cos(v*i)*(radius+radius/2)+cx;
float dy=(float) Math.sin(v*i)*(radius+radius/2)+cy;
float dx1=(float) Math.cos(v*i)*(radius*2)+cx;
float dy1=(float) Math.sin(v*i)*(radius*2)+cy;
canvas.drawLine(cx1,cy1,dx,dy,paint);
Rect rect=new Rect((int) dx1-40,(int)dy1+8,(int)dx1+40,(int)dy1-8);
SubTitle title=new SubTitle(datas.get(i-1),rect);
drawSubTitle(canvas,title);
subtitles.add(title);
}
}
paint.setColor(Color.WHITE);
canvas.drawText(MainTitle,cx,cy,paint);
}
public void drawSubTitle(Canvas canvas ,SubTitle title){
Paint paint=new Paint();
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.FILL);
paint.setTextSize(this.FontSize);
paint.setTextAlign(Paint.Align.CENTER);
paint.setColor(Color.BLUE);
if(title.getCatalog().getSelect()){
paint.setColor(Color.RED);
}
canvas.drawText(title.getCatalog().getName(), title.getRect().centerX(),title.getRect().centerY(),paint);
paint.setStyle(Paint.Style.STROKE);
canvas.drawRect(title.getRect().left,title.getRect().top,title.getRect().right,title.getRect().bottom,paint);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
float x=event.getX();
float y=event.getY();
for (SubTitle title :subtitles){
if(Math.abs(x-title.getRect().centerX())<80&&Math.abs(y-title.getRect().centerY())<40){
List<Catalog>calogs=new ArrayList<>();
for (Catalog catalog:datas){
if(catalog.getName().equals(title.getCatalog().getName())){
catalog.setSelect(true);
}else {catalog.setSelect(false);}
calogs.add(catalog);
}
this.datas=calogs;
invalidate(title.getRect());
click.onItemClick(this, title.getCatalog());
}
}
return false;
}
public interface OnItemClickListener{
void onItemClick(CompositeView compositeView, Catalog catalog);
}
/**
* 每个子标题的信息
*/
class SubTitle{
/**
* 子标题
*/
private Catalog catalog;
/**
* 范围位置
*/
private Rect rect;
public Rect getRect() {
return rect;
}
public void setRect(Rect rect) {
this.rect = rect;
}
public SubTitle(Catalog catalog, Rect rect) {
this.catalog = catalog;
this.rect = rect;
}
public Catalog getCatalog() {
return catalog;
}
public void setCatalog(Catalog catalog) {
this.catalog = catalog;
}
@Override
public String toString() {
return "SubTitle{" +
"catalog=" + catalog +
", rect=" + rect +
'}';
}
}
}
4、总结
革命尚未成功,程序还需改进,还是有很多东西做的不是自己最满意的
;再接再厉,自己给自己打气;