android的一些控件

原来朋友给过的一个 显示时间的 样例,还能够改动时间,可是要机子有root权限才干改动。

在这个时间表盘的样例基础上 改动改动  图片。背景图什么的      就能够达到自己想要的效果了。。

下载地址:  http://download.csdn.net/detail/kongbaidepao/8090083

1个风车效果的样例

是依据手滑动的速度 转动快慢的

代码不多,直接粘过来

public class MainActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        RotatView rotatView=(RotatView)findViewById(R.id.myRotatView);
        rotatView.setRotatDrawableResource(R.drawable.cycle);
    }

}
public class RotatView extends View {

    //原心坐标x
    float o_x;
    float o_y;

    /**
     * 处理惯性的handler
     */
    Handler handler;
   //handler处理消息的间隔
    int delayedTime = 20;

    /**
     * 消息信号,滚动的标识
     */
    static final int play = 0;

    /**
     * 消息信号,停止滚动的标识
     */
    static final int stop = 1;

    /**
     * 上次记录的时间,计算一定时间所走过的弧度、计算速度.
     */
    double currentTime = 0;

    /**
     * 图片的宽度
     */
    int width;

    /**
     * 图片的高度
     */
    int height;

    /**
     * view的真实宽度与高度:由于是旋转。所以这个view是正方形,它的值是图片的对角线长度
     */
    double maxwidth;

    /**
     * 旋转的图片
     */
    Bitmap rotatBitmap;

    public RotatView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();

    }

    /**
     * 初始化handler与速度计算器
     */
    private void init() {
        vRecord = new VRecord();
        handler = new Handler() {

            @Override
            public void handleMessage(Message msg) {

                double detaTime = System.currentTimeMillis() - currentTime;
                switch (msg.what) {

                    case play: {
                        if (isClockWise) {
                            speed = speed - a * detaTime;
                            if (speed <= 0) {
                                return;
                            } else {
                                handler.sendEmptyMessageDelayed(play, delayedTime);
                            }
                        } else {
                            speed = speed + a * detaTime;
                            if (speed >= 0) {
                                return;
                            } else {
                                handler.sendEmptyMessageDelayed(play, delayedTime);
                            }
                        }

                        addDegree((float)(speed * detaTime + (a * detaTime * detaTime) / 2));

                        // if (a < a_max) {
                        // a = (float)(a + a_add*detaTime);
                        // System.out.println("a:"+a);
                        // }
                        currentTime = System.currentTimeMillis();
                        invalidate();

                        break;
                    }
                    case stop: {
                        speed = 0;
                        handler.removeMessages(play);
                    }
                }

                super.handleMessage(msg);
            }
        };
        // 默认是有一张图片的

        initSize();
    }

    public void setRotatBitmap(Bitmap bitmap) {
        rotatBitmap = bitmap;
        initSize();
        postInvalidate();
    }

    public void setRotatDrawableResource(int id) {

        BitmapDrawable drawable = (BitmapDrawable)getContext().getResources().getDrawable(id);

        setRotatDrawable(drawable);
    }

    public void setRotatDrawable(BitmapDrawable drawable) {
        rotatBitmap = drawable.getBitmap();
        initSize();
        postInvalidate();
    }

    private void initSize() {
        if (rotatBitmap == null) {

            // throw new NoBitMapError("Error,No bitmap in RotatView!");
            return;
        }
        width = rotatBitmap.getWidth();
        height = rotatBitmap.getHeight();

        maxwidth = Math.sqrt(width * width + height * height);

        o_x = o_y = (float)(maxwidth / 2);//确定圆心坐标
    }

    /**
     * 通过此方法来控制旋转度数,假设超过360,让它求余,防止,该值过大造成越界
     *
     * @param added
     */
    private void addDegree(float added) {
        deta_degree += added;
        if (deta_degree > 360 || deta_degree < -360) {
            deta_degree = deta_degree % 360;
        }

    }

    @Override
    protected void onDraw(Canvas canvas) {

        Matrix matrix = new Matrix();
        // 设置转轴位置
        matrix.setTranslate((float)width / 2, (float)height / 2);

        // 開始转
        matrix.preRotate(deta_degree);
        // 转轴还原
        matrix.preTranslate(-(float)width / 2, -(float)height / 2);

        // 将位置送到view的中心
        matrix.postTranslate((float)(maxwidth - width) / 2, (float)(maxwidth - height) / 2);

        canvas.drawBitmap(rotatBitmap, matrix,paint);

        super.onDraw(canvas);
    }

    Paint paint=new Paint();
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        // TODO Auto-generated method stub
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        // 它的宽高不是图片的宽高,而是以宽高为直角的矩形的对角线的长度
        setMeasuredDimension((int)maxwidth, (int)maxwidth);

    }

    /**
     * 手指触屏的初始x的坐标
     */
    float down_x;

    /**
     * 手指触屏的初始y的坐标
     */
    float down_y;

    /**
     * 移动时的x的坐标
     */
    float target_x;

    /**
     * 移动时的y的坐标
     */
    float target_y;

    /**
     * 放手时的x的坐标
     */
    float up_x;

    /**
     * 放手时的y的坐标
     */
    float up_y;

    /**
     * 当前的弧度(以该 view 的中心为圆点)
     */
    float current_degree;

    /**
     * 放手时的弧度(以该 view 的中心为圆点)
     */
    float up_degree;

    /**
     * 当前圆盘所转的弧度(以该 view 的中心为圆点)
     */
    float deta_degree;

    /**
     * 最后一次手势滑过的时间
     */
    double lastMoveTime = 0;

    /**
     * 最小加速度(当手指放手是)
     */
    public static final float a_min = 0.001f;

    /**
     * 加速度增量
     */
    public static final float a_add = 0.001f;

    /**
     * 加速度
     */
    float a = a_min;

    /**
     * 最大加速度(当手指按住时)
     */
    public static final float a_max = a_min * 5;

    /**
     * 旋转速度(度/毫秒)
     */
    double speed = 0;

    /**
     * 速度计算器
     */
    VRecord vRecord;

    /**
     * 是否为顺时针旋转
     */
    boolean isClockWise;

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

            throw new NoBitMapError("Error,No bitmap in RotatView!");
        }
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN: {
                down_x = event.getX();
                down_y = event.getY();
                current_degree = detaDegree(o_x, o_y, down_x, down_y);
                vRecord.reset();
                // handler.sendEmptyMessage(stop);
                a = a_max;

                break;

            }
            case MotionEvent.ACTION_MOVE: {
                down_x = target_x = event.getX();
                down_y = target_y = event.getY();
                float degree = detaDegree(o_x, o_y, target_x, target_y);

                // 滑过的弧度增量
                float dete = degree - current_degree;
                // 假设小于-90度说明 它跨周了,须要特殊处理350->17,
                if (dete < -270) {
                    dete = dete + 360;

                    // 假设大于90度说明 它跨周了,须要特殊处理-350->-17,
                } else if (dete > 270) {
                    dete = dete - 360;
                }
                lastMoveTime = System.currentTimeMillis();
                vRecord.add(dete, lastMoveTime);
                addDegree(dete);
                current_degree = degree;
                postInvalidate();

                break;
            }
            case MotionEvent.ACTION_CANCEL:
            case MotionEvent.ACTION_UP: {
                a = a_min;

                double lastupTime = System.currentTimeMillis();
                double detaTime = lastupTime - lastMoveTime;
                up_x = event.getX();
                up_y = event.getY();
                up_degree = detaDegree(o_x, o_y, up_x, up_y);
                // 放手时的速度
                speed = speed + vRecord.getSpeed();
                if (speed > 0) {
                    speed = Math.min(VRecord.max_speed, speed);
                } else {
                    speed = Math.max(-VRecord.max_speed, speed);
                }
//                System.out.println("speed:" + speed);
                if (speed > 0) {
                    isClockWise = true;
                    // v = 1;
                } else {
                    isClockWise = false;
                    // v = -1;
                }
                currentTime = System.currentTimeMillis();
                handler.sendEmptyMessage(0);
                break;
            }
        }
        return true;
    }

    /**
     * 计算以(src_x,src_y)为坐标圆点,建立直角体系,求出(target_x,target_y)坐标与x轴的夹角
     * 主要是利用反正切函数的知识求出夹角
     *
     * @param src_x
     * @param src_y
     * @param target_x
     * @param target_y
     * @return
     */
    float detaDegree(float src_x, float src_y, float target_x, float target_y) {

        float detaX = target_x - src_x;
        float detaY = target_y - src_y;
        double d;
        if (detaX != 0) {
            float tan = Math.abs(detaY / detaX);

            if (detaX > 0) {

                if (detaY >= 0) {
                    d = Math.atan(tan);

                } else {
                    d = 2 * Math.PI - Math.atan(tan);
                }

            } else {
                if (detaY >= 0) {

                    d = Math.PI - Math.atan(tan);
                } else {
                    d = Math.PI + Math.atan(tan);
                }
            }

        } else {
            if (detaY > 0) {
                d = Math.PI / 2;
            } else {

                d = -Math.PI / 2;
            }
        }

        return (float)((d * 180) / Math.PI);
    }

    /**
     * 一个异常。用来推断是否有rotatbitmap
     *
     * @author sun.shine
     */
    static class NoBitMapError extends RuntimeException {

        /**
         *
         */
        private static final long serialVersionUID = 1L;

        public NoBitMapError(String detailMessage) {
            super(detailMessage);
        }

    }

    /**
     * 速度计算器 原来是将近期的 弧度增量和时间点记录下来,然后<br>
     * 通过增量除以总时间求出平均值做为它的即时手势滑过的速度
     *
     * @author sun.shine
     */
    static class VRecord {

        /**
         * 数组中的有效数字
         */
        int addCount;

        /**
         * 最大能装的数据空间
         */
        public static final int length = 15;

        /**
         * 二维数组,1.保存弧度增量.2.保存产生这个增量的时间点
         */
        double[][] record = new double[length][2];

        /**
         * 为二维数组装载数据<br>
         * 注:通过此方法,有个特点,能把最后的length组数据记录下来,length以外的会丢失
         *
         * @param detadegree
         * @param time
         */
        public void add(double detadegree, double time) {

            for (int i = length - 1; i > 0; i--) {
                record[i][0] = record[i - 1][0];
                record[i][1] = record[i - 1][1];
            }
            record[0][0] = detadegree;
            record[0][1] = time;
            addCount++;

        }

        /**
         * 最大速度
         */
        public static final double max_speed = 8;

        /**
         * 通过数组里所装载的数据分析出即时速度<br>
         * 原理是:计算数组里的时间长度和增量的总数。然后求出每毫秒所走过的弧度<br>
         * 当然不能超过{@link VRecord#max_speed}
         *
         * @return
         */
        public double getSpeed() {

            if (addCount == 0) {
                return 0;
            }
            int maxIndex = Math.min(addCount, length) - 1;

            if ((record[0][1] - record[maxIndex][1]) == 0) {
                return 0;
            }

            double detaTime = record[0][1] - record[maxIndex][1];
            double sumdegree = 0;
            for (int i = 0; i < length - 1; i++) {

                sumdegree += record[i][0];
                // System.out.println(record[i][0]);
            }

            // System.out.println("----------");
            // System.out.println(sumdegree);
            // System.out.println(detaTime);
            double result = sumdegree / detaTime;
            if (result > 0) {
                return Math.min(result, max_speed);
            } else {
                return Math.max(result, -max_speed);
            }
            // System.out.println("v=" + result);

        }

        /**
         * 重置
         */
        public void reset() {
            addCount = 0;
            for (int i = length - 1; i > 0; i--) {
                record[i][0] = 0;
                record[i][1] = 0;
            }
        }
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        if(rotatBitmap!=null){
        rotatBitmap.recycle();
        rotatBitmap=null;
        }
    }
}
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="#ffffffff" >

    <com.sun.shine.myrotation.view.RotatView
        android:id="@+id/myRotatView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="10dip" >
    </com.sun.shine.myrotation.view.RotatView>

</RelativeLayout>
时间: 2024-11-04 23:25:54

android的一些控件的相关文章

Android中用seekbar控件控制歌曲的进度

本人菜鸟一枚,在编写android中用seekbar控件控制歌曲的进度和seekbar随着歌曲的播放自动运动的程序有一些自己的见解,希望各位大牛们多多指点······ 废话先不多说了,先贴一张程序的图吧: 界面不怎么好看,没经过美化,大家将就这看一下吧. 主要思路是运用线程每隔一秒显示一下seekbar控件所在的位置,(这个是使进度条随着歌曲的进度而不断的变化,如果大家想使进度条增加的更连续,可以改变程序循环运行的时间,使其更快) 我只把关于seekbar的程度拿出来了: private int

android学习五(android中基本控件的使用)

前面已经学了activity的一些使用,那么下面我们进行android中基本的控件的学习和使用. 1.android中的TextView控件 新建一个项目,项目名为UITest,才有默认的设置,修改布局文件的内容,如下: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" a

【ANDROID 初学】控件--IMAGEVIEW的使用方法

Start Android 1.图片视图(ImageView)的基本概念 2.<InameView/>与ImageView 3.神奇的ScaleType属性 当图片大小与ImageView大小不匹配的时候,可以通过该属性来调整图片与ImageView控件的位置关系. android:scaleType:  android:scaleType是控制图片如何resized/moved来匹对ImageView的size. ImageView.ScaleType / android:scaleType

Android 遍历界面控件

//遍历界面上的控件 fubin.pan LinearLayout sLinerLayout = (LinearLayout)findViewById(R.id.layout_scr); for (int i = 0; i < sLinerLayout.getChildCount(); i++) { View v=sLinerLayout.getChildAt(i); if ( v instanceof RadioGroup){ RadioGroup mRadioGroup = (RadioGr

Android 中常见控件的介绍和使用

1 TextView文本框 1.1 TextView类的结构 TextView 是用于显示字符串的组件,对于用户来说就是屏幕中一块用于显示文本的区域.TextView类的层次关系如下: java.lang.Object   ? android.view.View   ? android.widget.TextView 直接子类: Button, CheckedTextView, Chronometer, DigitalClock, EditText 间接子类: AutoCompleteTextV

Android两个控件叠在一起,如何让被挡住的控件显示出来

Android两个控件叠在一起,如何让被挡住的控件显示出来 问题 : 两个控件叠在一起,如何让被挡住的控件显示出来? 比如A,B两个控件,A被B挡住,目前A要显示出来,B不能被隐藏,A的高度只有那么一点,显示出来的时候,B不能隐藏. 其实很简单 A.bringToFront即可.

xamarin android——数据绑定到控件(四)

本文为通过自定义列表适配器定义ListView,以上文为基础,基于ListActivity. 定义列表项布局,包含一个图片显示,标题和描述 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="80dip"> <ImageV

xamarin android——数据绑定到控件(三)

如果当前活动中,只存在一个listview视图,可以借助ListActivity快速的实现一个列表,即当前Activity继承ListActivity.在OnCreate方法中简单的两行代码,就可以创建一个用户列表. string[] items = new string[]{ "列表 1","列表 2","列表 3","列表 4","列表 5","列表 6","列表 7&qu

Android M新控件之AppBarLayout,NavigationView,CoordinatorLayout,CollapsingToolbarLayout的使用

[转载请注明出处:http://blog.csdn.net/feiduclear_up/article/details/46514791 CSDN 废墟的树] 上一篇博客我们学习了Android Design Support Library库中的 是个简单的组件,不了解的童鞋可以参考之前的博客 Android M新控件之FloatingActionButton,TextInputLayout,Snackbar,TabLayout的使用. 这篇博客我们继续学习Design库中的其他四个组件,分别是

Android自己定义控件皮肤

Android自己定义控件皮肤 对于Android的自带控件,其外观仅仅能说中规中矩,而我们平时所示Android应用中,一个简单的button都做得十分美观.甚至于很多button在按下时的外观都有一定变化,用户体验十分好. 这当中,就涉及到了Android自己定义控件属性的操作方法,下面操作以实现自己定义button皮肤为例. 1. 我们要自己定义将要实现的外观状态.能够是图片或者是自己定义的xml,这是我们直接自己定义不同状态的颜色xml,在values文件夹下新建colors.xml,代