文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

android自定义控件是怎么实现简易时间轴

2023-06-28 23:54

关注

这篇文章主要为大家分析了android自定义控件是怎么实现简易时间轴的相关知识点,内容详细易懂,操作细节合理,具有一定参考价值。如果感兴趣的话,不妨跟着跟随小编一起来看看,下面跟着小编一起深入学习“android自定义控件是怎么实现简易时间轴”的知识吧。

之前项目需要写一个消费记录,类似于时间轴似的控件,自身在自定义控件这里不咋地(…),最后搞了一个这个demo

效果图:

android自定义控件是怎么实现简易时间轴

这里就是绘制圆和上下两条线

资源文件,定义一些基本的属性:

<?xml version="1.0" encoding="utf-8"?><resources>    <attr name="textSize" format="dimension" />    <attr name="textColor" format="color" />    <attr name="textTitle" format="string" />    <attr name="borderColor" format="color" />    <attr name="borderWidth" format="dimension" />    <attr name="lineColor" format="color" />    <attr name="lineWidth" format="dimension" />    <attr name="bgColor" format="color" />    <attr name="mRadius" format="dimension"/>    <declare-styleable name="CustomCicleView">        <attr name="textSize" />        <attr name="textColor" />        <attr name="textTitle" />        <attr name="lineColor" />        <attr name="lineWidth" />        <attr name="bgColor" />        <attr name="borderColor" />        <attr name="borderWidth" />           <attr name="mRadius" />    </declare-styleable></resources>

获取属性:

int attr=a.getIndex(i);        switch (attr) {            case R.styleable.CustomCicleView_textSize:                  // 默认设置为16sp,TypeValue也可以把sp转化为px                  mTextSize = a.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(                          TypedValue.COMPLEX_UNIT_PX, 14, getResources().getDisplayMetrics()));                 break;            case R.styleable.CustomCicleView_textColor:                mTextColor=a.getColor(attr, Color.BLACK);                break;            case R.styleable.CustomCicleView_lineWidth:                mLineWidth= a.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(                          TypedValue.COMPLEX_UNIT_PX, 2, getResources().getDisplayMetrics()));                  break;            case R.styleable.CustomCicleView_lineColor:                mLineColor=a.getColor(attr, lineColr);                break;            case R.styleable.CustomCicleView_borderWidth:                mBorderWidth= a.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(                          TypedValue.COMPLEX_UNIT_PX, 2, getResources().getDisplayMetrics()));                  break;            case R.styleable.CustomCicleView_borderColor:                mBorderColor=a.getColor(attr, borderColor);                break;            case R.styleable.CustomCicleView_bgColor:                mBgColor=a.getColor(attr, bgColor);                break;            }

这里主要释放资源方便回收:

a.recycle();//官方API的解释是:给回一个先前的提取的数组,为以后复用,,就是当前的对象回收,下次要用的时候就不用重新再new一个新的对象了,直接从它的回收池里面拿就行。public void recycle ():Give back a previously retrieved array, for later re-use

重要绘制代码:

 super.onDraw(canvas);      int centre = getWidth() / 2; // 获取圆心的x坐标        //半径比较        int mixWidth=getMeasuredWidth()>getMeasuredHeight()?getMeasuredHeight():getMeasuredWidth();        mRadius =mRadius>(mixWidth)?(mixWidth):mRadius;        mBorderWidth =mRadius/2>=(mBorderWidth)?(mBorderWidth):mRadius/10;//最终的效果要不是自己设置的要不就是半径的1/5        int radius = mRadius/2 - mBorderWidth / 2;// 半径        mLineHeight=Math.abs(getHeight()/2-radius);//这个地方要判断设置正负        if(lineLocation!=-1){            drawLine(canvas,centre);        }        //绘制背景        bgPaint.setColor(Color.parseColor("#00000000"));        bgPaint.setTextSize(mTextSize);        canvas.drawRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), bgPaint);        //绘制圆        bgPaint.setAntiAlias(true); // 消除锯齿        bgPaint.setColor(mBgColor);        bgPaint.setStyle(Paint.Style.FILL); // 设置实心        canvas.drawCircle(centre, centre, radius, bgPaint);        //绘制圆环        borderPaint.setStrokeWidth(mBorderWidth); // 设置圆环的宽度        borderPaint.setAntiAlias(true); // 消除锯齿        if (mBorderColor != 0) {            borderPaint.setColor(mBorderColor);        } else {            borderPaint.setColor(borderColor);        }        borderPaint.setStyle(Paint.Style.STROKE); // 设置实心        canvas.drawCircle(centre,centre, radius - mBorderWidth / 2+mLineWidth/2, borderPaint);        //绘制文本        bgPaint.setColor(mTextColor);        textPaint.getTextBounds(mTextTitle, 0, mTextTitle.length(), textRect);        canvas.drawText(mTextTitle, centre -textRect.width()/2, centre  + textRect.height() / 2, bgPaint);

这里给了一个int值来判断当前需要绘制那个位置的line;值是0只需绘制 上方line,值是 1只需绘制下方line,值是2同事绘制上下方line,值是-1不需绘制line;这个值由用户使用的时候传递过来这样就可以绘制对应的line

 //0  上方 1  下方 2  上下两个    private void drawLine(Canvas canvas, float centre) {        linePaint.setColor(borderColor);        linePaint.setStrokeWidth(mLineWidth);        if (lineLocation == 0) {//          canvas.drawLine(centre, 0.5F*centre-mLineHeight, centre, centre, linePaint);             canvas.drawLine(centre, 0, centre, mLineHeight*2, linePaint);        } else if (lineLocation == 1) {            canvas.drawLine(centre, centre, centre, centre * 2F + mLineHeight, linePaint);        } else if (lineLocation == 2) {//            canvas.drawLine(centre, mRadius * 0.5F - mLineHeight-mBorderWidth, centre, mLineHeight, linePaint);            canvas.drawLine(centre, 0, centre, mLineHeight*2, linePaint);            canvas.drawLine(centre, centre, centre, centre * 2F + mLineHeight, linePaint);        }    }

使用

这里的使用有两种,一种是在xml中直接布局,设置属性,一种是在代码中初始化然后根据提供的set方法来设置相应的属性。
在你布局中使用的时候要加上
xmlns:app=”http://schemas.android.com/apk/res/com.example.circleview”
com.example.circleview:是包名
这样你就可以设置这个控件的属性了

<com.example.circleview.CircleImg        android:id="@+id/itemImg"        android:layout_width="100dp"        android:layout_height="100dp"        android:layout_margin="2dp"        app:bgColor="#f88"        app:borderColor="#138ddd"        app:textColor="#fff"        app:textSize="12dp" />

最终效果:

android自定义控件是怎么实现简易时间轴

基本的一个圆就好了,现在来实现开始的时候的效果图,基本就是用listView实现:
布局文件

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    xmlns:app="http://schemas.android.com/apk/res/com.example.circleview"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:layout_margin="5dp"    android:orientation="vertical"    tools:context="com.example.circleview.MainActivity" >    <ListView        android:id="@+id/listView"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:divider="#00000000"        android:dividerHeight="0dp"      >    </ListView></LinearLayout>

MainActivity.java:

public class MainActivity extends Activity {    private List<String> list=new ArrayList<String>();    ListView listView;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        initData();        listView=(ListView) findViewById(R.id.listView);        listView.setAdapter(new TimeLineAdapter(list, this));    }    private void initData() {        for (int i =11; i >1; i--) {//时间从小到大        list.add("05/"+i);          }    }}

Adapter:

public class TimeLineAdapter extends BaseAdapter {    private static final int[] COLOR = new int[] {              0xff33b5e5, 0xffaa66cc, 0xff99cc00, 0xffffbb33, 0xffff4444,0xff009933,0xffff9988,  0xffffddcc,0xff00ffff,0xffffff00        };     private List<String> list;    private Context context;    private ViewHolder holder;    public TimeLineAdapter(List<String> list, Context context) {        super();        this.list = list;        this.context = context;    }    @Override    public int getCount() {        // TODO Auto-generated method stub        return list.size();    }    @Override    public Object getItem(int position) {        // TODO Auto-generated method stub        return list.get(position);    }    @Override    public long getItemId(int position) {        return position;    }    @Override    public View getView(int position, View convertView, ViewGroup parent) {         int type = getItemViewType(position);        if(convertView==null){            convertView=View.inflate(context, R.layout.item,null);            holder=new ViewHolder();            convertView.setTag(holder);            holder.img=(CircleImg) convertView.findViewById(R.id.itemImg);            holder.item=(TextView) convertView.findViewById(R.id.itemText);        }else{            holder=(ViewHolder) convertView.getTag();        }        holder.img.setBgAndBorderColor(COLOR[position%10]);        holder.img.invalidate();//记得重绘        holder.img.setLineLocation(type);        holder.img.setmTextTitle(list.get(position));        holder.item.setText("哈哈哈哈哈哈哈哈");        return convertView;    }    @Override    public int getItemViewType(int position) {          final int size = list.size() - 1;            if (size == 0)                return ItemType.ATOM;            else if (position == 0)                return ItemType.FOOTER;            else if (position == size)                return ItemType.HEADER;            else return ItemType.NORMAL;    }    class ViewHolder{        TextView item;        CircleImg img;    }}

这里绘制上下line的时候是通过getItemViewType()返回的view id值来判断的,ItemType中有四个变量:

public final static int NORMAL = 2;  //表示绘制上下方public final static int HEADER = 0;  //表示绘制下方public final static int FOOTER = 1;  //表示绘制上方public final static int ATOM = -1;   //表示不绘制

然后通过holder.img.setLineLocation(type);来设置当前绘制的line。

CIcleVIew.java下:

public class CircleImg extends View {    //画笔    private Paint bgPaint, linePaint, borderPaint,textPaint;    private Rect bgRect, textRect;    //基本属性    private int mTextSize;    private int mTextColor;    private String mTextTitle;    private int lineColr = Color.parseColor("#AAAAAA");    private int borderColor = Color.parseColor("#AAAAAA");    private int bgColor = Color.parseColor("#138DDD");    private int mBorderColor;    private int mBorderWidth = 2;    private int mLineColor;    private int mLineWidth = 2;    private int mLineHeight;    private int mBgColor;    //line绘制    private int lineLocation = -1;//0  上方 1  下方 2  上下两个    private int mRadius = 40;    public CircleImg(Context context) {        this(context, null);    }    //设置line的位置 0  上方 1  下方 2  上下两个    public void setLineLocation(int lineLocation) {        this.lineLocation = lineLocation;    }    //设置纯色的整圆形,包括背景    public void setBgAndBooderCOlor(int color) {        this.mBorderColor = color;        this.mBgColor = color;    }    public void setmTextTitle(String mTextTitle) {        this.mTextTitle = mTextTitle;    }    public void setmRadius(int mRadius) {        this.mRadius = mRadius;    }    public CircleImg(Context context, AttributeSet attrs) {        this(context, attrs, 0);        // TODO Auto-generated constructor stub    }    public CircleImg(Context context, AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);        TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CustomCicleView, defStyle, 0);        int n = a.getIndexCount();        for (int i = 0; i < n; i++) {            int attr = a.getIndex(i);            switch (attr) {                case R.styleable.CustomCicleView_textSize:                    // 默认设置为16sp,TypeValue也可以把sp转化为px                    mTextSize = a.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(                            TypedValue.COMPLEX_UNIT_PX, 14, getResources().getDisplayMetrics()));                    break;                case R.styleable.CustomCicleView_textColor:                    mTextColor = a.getColor(attr, Color.BLACK);                    break;                case R.styleable.CustomCicleView_textTitle:                    mTextTitle = a.getString(attr);                    break;                case R.styleable.CustomCicleView_lineWidth:                    mLineWidth = a.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(                            TypedValue.COMPLEX_UNIT_PX, 2, getResources().getDisplayMetrics()));                    break;                case R.styleable.CustomCicleView_lineColor:                    mLineColor = a.getColor(attr, lineColr);                    break;                case R.styleable.CustomCicleView_mRadius:                    mRadius=a.getInt(attr,40);                    break;                case R.styleable.CustomCicleView_borderWidth:                    mBorderWidth = a.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(                            TypedValue.COMPLEX_UNIT_PX, 2, getResources().getDisplayMetrics()));                    break;                case R.styleable.CustomCicleView_borderColor:                    mBorderColor = a.getColor(attr, borderColor);                    break;                case R.styleable.CustomCicleView_bgColor:                    mBgColor = a.getColor(attr, bgColor);                    break;            }        }        a.recycle();        bgPaint = new Paint();        borderPaint = new Paint();        linePaint = new Paint();        textPaint = new Paint();        textRect = new Rect();        textPaint.setTextSize(mTextSize);    }    //暂时不计算    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        int w = getPaddingLeft() + getPaddingRight();        int h = getPaddingTop() + getPaddingBottom();        if (bgPaint != null) {            w += mRadius;            h += mRadius;        }        w = Math.max(w, getMeasuredWidth());        h = Math.max(h, getMeasuredHeight());        int widthSize = resolveSizeAndState(w, widthMeasureSpec, 0);        int heightSize = resolveSizeAndState(h, heightMeasureSpec, 0);        setMeasuredDimension(widthSize, heightSize);    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);       int centre = getWidth() / 2; // 获取圆心的x坐标        int radius = mRadius - mBorderWidth / 2;// 半径        mLineHeight=getHeight()/2-radius;//这个地方要判断设置正负        if(lineLocation!=-1){            drawLine(canvas,centre);        }        //绘制背景        bgPaint.setColor(Color.parseColor("#00000000"));        bgPaint.setTextSize(mTextSize);        canvas.drawRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), bgPaint);        //绘制圆        bgPaint.setAntiAlias(true); // 消除锯齿        bgPaint.setColor(mBgColor);        bgPaint.setStyle(Paint.Style.FILL); // 设置实心        canvas.drawCircle(centre, centre, radius, bgPaint);        //绘制圆环        borderPaint.setStrokeWidth(mBorderWidth); // 设置圆环的宽度        borderPaint.setAntiAlias(true); // 消除锯齿        if (mBorderColor != 0) {            borderPaint.setColor(mBorderColor);        } else {            borderPaint.setColor(borderColor);        }        borderPaint.setStyle(Paint.Style.STROKE); // 设置实心        canvas.drawCircle(centre,centre, radius - mBorderWidth / 2+mLineWidth/2, borderPaint);        //绘制文本        bgPaint.setColor(mTextColor);        textPaint.getTextBounds(mTextTitle, 0, mTextTitle.length(), textRect);        canvas.drawText(mTextTitle, centre -textRect.width()/2, centre  + textRect.height() / 2, bgPaint);    }    //0  上方 1  下方 2  上下两个    private void drawLine(Canvas canvas, float centre) {        linePaint.setColor(borderColor);        linePaint.setStrokeWidth(mLineWidth);        if (lineLocation == 0) {            canvas.drawLine(centre, centre, centre, centre * 2F + mLineHeight, linePaint);        } else if (lineLocation == 1) {            canvas.drawLine(centre, 0, centre, mLineHeight*2, linePaint);        } else if (lineLocation == 2) {            canvas.drawLine(centre, 0, centre, mLineHeight*2, linePaint);            canvas.drawLine(centre, centre, centre, centre * 2F + mLineHeight, linePaint);        }    }}

styleable.xml:

<?xml version="1.0" encoding="utf-8"?><resources>    <attr name="textSize" format="dimension" />    <attr name="textColor" format="color" />    <attr name="textTitle" format="string" />    <attr name="borderColor" format="color" />    <attr name="borderWidth" format="dimension" />    <attr name="lineColor" format="color" />    <attr name="lineWidth" format="dimension" />    <attr name="bgColor" format="color" />    <attr name="mRadius" format="dimension"/>    <declare-styleable name="CustomCicleView">        <attr name="textSize" />        <attr name="textColor" />        <attr name="textTitle" />        <attr name="lineColor" />        <attr name="lineWidth" />        <attr name="bgColor" />        <attr name="borderColor" />        <attr name="borderWidth" />           <attr name="mRadius" />    </declare-styleable></resources>

Android是什么

Android是一种基于Linux内核的自由及开放源代码的操作系统,主要使用于移动设备,如智能手机和平板电脑,由美国Google公司和开放手机联盟领导及开发。

关于“android自定义控件是怎么实现简易时间轴”就介绍到这了,更多相关内容可以搜索编程网以前的文章,希望能够帮助大家答疑解惑,请多多支持编程网网站!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯