android 连线题实现 自定义view  画线

项目新需求  要来个连线题...

这里写图片描述

这个是后来加了点击效果的
效果图  这个只是基本的逻辑实现了   具体要做的话还需要继续完善 .核心代码已经写出来了

剩下的就是 体力活 完善界面 和其他的一些逻辑了 比如按下的效果 画线的颜色宽度.等等.

下面是核心代码  如果需要下载 后面有下载链接

package com.example.customview01.view;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Random;
import java.util.Set;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Cap;
import android.graphics.Point;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.View;

import com.example.customview01.MLog;
import com.example.customview01.R;

public class MyView extends View {

    String pointText[] = { "第一", "第二", "第三", "第四" };
    String reaAnswer[] = { "13", "24" };

    List<MyLine> list;
    List<Point> beginList;
    private int selectLine;// 当前画的第几条线
    //
    /**
     * 文本
     */
    private String mTitleText;
    /**
     * 文本的颜色
     */
    private int mTitleTextColor;
    /**
     * 文本的大小
     */
    private int mTitleTextSize;

    Paint linePaint = new Paint();
    private float width, height;

    //
    // /**
    // * 绘制时控制文本绘制的范围
    // */
    private Rect mBound;
    private Paint mPaint;

    public MyView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MyView(Context context) {
        this(context, null);
    }

    /**
     * 获得我自定义的样式属性
     * 
     * @param context
     * @param attrs
     * @param defStyle
     */
    public MyView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        /**
         * 获得我们所定义的自定义样式属性
         */
        TypedArray a = context.getTheme().obtainStyledAttributes(attrs,
                R.styleable.MyView, defStyle, 0);
        int n = a.getIndexCount();
        for (int i = 0; i < n; i++) {
            int attr = a.getIndex(i);
            switch (attr) {
            case R.styleable.MyView_titleText:
                mTitleText = a.getString(attr);
                break;
            case R.styleable.MyView_titleTextColor:
                // 默认颜色设置为黑色
                mTitleTextColor = a.getColor(attr, Color.BLACK);
                break;
            case R.styleable.MyView_titleTextSize:
                // 默认设置为16sp,TypeValue也可以把sp转化为px
                mTitleTextSize = a.getDimensionPixelSize(attr, (int) TypedValue
                        .applyDimension(TypedValue.COMPLEX_UNIT_SP, 16,
                                getResources().getDisplayMetrics()));
                break;

            }

        }
        a.recycle();

        initData();

        /**
         * 获得绘制文本的宽和高
         */
        mPaint = new Paint();
        mPaint.setTextSize(mTitleTextSize);
        // mPaint.setColor(mTitleTextColor);
        mBound = new Rect();
        mPaint.getTextBounds(mTitleText, 0, mTitleText.length(), mBound);


    }

    /**
     * 初始化数据
     */
    private void initData() {
        // TODO Auto-generated method stub
        initLinePaint();
        list = new ArrayList<MyLine>();
        // 初始化
        // 根据答案个数 将自定义view分成几块 然后获取每个选项的x y 点

    }

    private void initLinePaint() {
        // TODO Auto-generated method stub
        linePaint.setColor(Color.RED);
        linePaint.setStrokeWidth(20);
        linePaint.setAntiAlias(true);
        linePaint.setStrokeCap(Cap.ROUND);
    }



    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        // super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        int width = 0;
        int height = 0;

        /**
         * 设置宽度
         */
        int specMode = MeasureSpec.getMode(widthMeasureSpec);
        int specSize = MeasureSpec.getSize(widthMeasureSpec);
        switch (specMode) {
        case MeasureSpec.EXACTLY:// 明确指定了
            width = getPaddingLeft() + getPaddingRight() + specSize;
            break;
        case MeasureSpec.AT_MOST:// 一般为WARP_CONTENT
            width = getPaddingLeft() + getPaddingRight() + mBound.width();
            break;
        }

        /**
         * 设置高度
         */
        specMode = MeasureSpec.getMode(heightMeasureSpec);
        specSize = MeasureSpec.getSize(heightMeasureSpec);
        switch (specMode) {
        case MeasureSpec.EXACTLY:// 明确指定了
            height = getPaddingTop() + getPaddingBottom() + specSize;
            break;
        case MeasureSpec.AT_MOST:// 一般为WARP_CONTENT
            height = getPaddingTop() + getPaddingBottom() + mBound.height();
            break;
        }

        setMeasuredDimension(width, height);

        initAnswerPoint();

    }

    private void initAnswerPoint() {
        beginList = new ArrayList<Point>();
        // 根据答案个数 将自定义view分成几块 然后初始化每个选项的x y 点
        MLog.d("宽 = " + getMeasuredWidth() + "  高 = " + getMeasuredHeight());
        int size = pointText.length;
        for (int i = 0; i < size; i++) {
            beginList.add(getPoint(i));
        }

    }

    // 根据传入的答案返回返回线的点
    private Point getPoint(final int select) {
        Point point = null;
        // TODO Auto-generated method stub
        int size = pointText.length;
        MLog.d("==宽度  = " + getMeasuredWidth() + "      高度  = "
                + getMeasuredHeight());
        int item = getMeasuredHeight() / size;
        int x = 0, y = 0;

        switch (select) {
        case 0:
            x = 0;
            y = item;
            break;
        case 1:
            x = getMeasuredWidth();
            y = item;
            break;
        case 2:
            x = 0;
            y = item * (select + 1);
            break;
        case 3:
            x = getMeasuredWidth();
            y = item * (select);
            break;

        default:
            break;
        }
        point = new Point(x, y);
        return point;
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        // TODO Auto-generated method stub

        MLog.d("觸摸事件");
        MLog.d("宽 = " + getMeasuredWidth() + "  高 = " + getMeasuredHeight());
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:

            MLog.d("按下事件  x = " + event.getX() + " y= " + event.getY());
            break;
        case MotionEvent.ACTION_MOVE:
            MLog.d("移動事件  x = " + event.getX() + " y= " + event.getY());
            break;
        case MotionEvent.ACTION_UP:
            MLog.d("移動事件  x = " + event.getX() + " y= " + event.getY());

            break;

        default:
            break;
        }
        return super.onTouchEvent(event);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        mPaint.setColor(Color.YELLOW);
        canvas.drawRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), mPaint);

        mPaint.setColor(mTitleTextColor);

        if (list != null && list.size() > 0) {

            for (int i = 0; i < list.size(); i++) {
                drawLine(list.get(i), canvas);
            }
        }

    }

    /**
     * 根据答案 判断当前选择的是那一条线 并進行設置
     * 
     * @param answer1
     * @param answer2
     */
    public void setLine(int answer1, int answer2) {
        // list.get(location)
        // 如果没满 或者不存在 那么给他添加 否则 进行设置
        if (!isExists(answer1, answer2)) {

            if(isSameSide(answer1,answer2)){
                return;
            }
            // 或者
            String str = String.valueOf(answer1) + String.valueOf(answer2);
            MLog.d("存入的答案 = " + str);
            MyLine myLine = new MyLine(getPoint(answer1), getPoint(answer2),
                    str);
            list.add(myLine);
        } else {
            if(isSameSide(answer1,answer2)){
                return;
            }
            for (int i = 0; i < list.size(); i++) {

                MyLine myLine = list.get(i);
                if (myLine.anwer.contains(String.valueOf(answer1))
                        || myLine.anwer.contains(String.valueOf(answer2))) {
                    list.set(
                            i,
                            new MyLine(getPoint(answer1), getPoint(answer2),
                                    String.valueOf(answer1)
                                            + String.valueOf(answer2)));
                }
            }
        }

        invalidate();
    }

    /**
     * 是否是同一侧
     * @param answer1
     * @param answer2
     * @return
     */
    private boolean isSameSide(int answer1, int answer2) {
        if (answer1 % 2 == 0 && answer2 % 2 == 0) {//同一侧
            // i为偶数
            return true;
        } 
        if (answer1 % 2 != 0 && answer2 % 2 != 0) {//同一侧
            // i为奇数
            return true;
        }
        return false; 


    }

    /**
     * 根据传入的答案判断 是否已经存入数据
     * 
     * @param anwer1
     * @param anwer2
     * @return
     */
    private boolean isExists(int answer1, int answer2) {
        if (list.size() <= 0) {
            return false;
        }
        for (int i = 0; i < list.size(); i++) {
            MyLine myLine = list.get(i);
            if (myLine.anwer != null
                    && (myLine.anwer.contains(String.valueOf(answer1)) || myLine.anwer
                            .contains(String.valueOf(answer2)))) {
                return true;
            }
        }
        return false;
    }

    /**
     * 画线
     * 
     * @param myLine
     * @param canvas
     */
    private void drawLine(MyLine myLine, Canvas canvas) {

        canvas.drawLine(myLine.getStartx(), myLine.getStarty(),
                myLine.getEndx(), myLine.getEndy(), linePaint);
    }

    class MyLine {

        int startx;
        int starty;
        int endx;
        int endy;
        String anwer;

        public MyLine(Point point1, Point point2, String answer1) {
            this.startx = point1.x;
            this.starty = point1.y;
            this.endx = point2.x;
            this.endy = point2.y;
            this.anwer = answer1;
        }

        public String getAnwer() {
            return anwer;
        }

        public void setAnwer(String anwer) {
            this.anwer = anwer;
        }

        public int getStartx() {
            return startx;
        }

        public void setStartx(int startx) {
            this.startx = startx;
        }

        public int getStarty() {
            return starty;
        }

        public void setStarty(int starty) {
            this.starty = starty;
        }

        public int getEndx() {
            return endx;
        }

        public void setEndx(int endx) {
            this.endx = endx;
        }

        public int getEndy() {
            return endy;
        }

        public void setEndy(int endy) {
            this.endy = endy;
        }

        @Override
        public String toString() {
            return "MyLine [startx=" + startx + ", starty=" + starty
                    + ", endx=" + endx + ", endy=" + endy + ", anwer=" + anwer
                    + "]";
        }

    }
}

http://download.csdn.net/detail/liudao7994/9664824 下载地址 新加了textview状态选中

评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值