规模和对齐定制的Andr​​oid AnalogClock手 [英] Scale and align in custom android AnalogClock hands

查看:233
本文介绍了规模和对齐定制的Andr​​oid AnalogClock手的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我搜索的话题了好几天,最后还是一头雾水。我们的想法是创建自己的闹钟应用了一些特殊的技巧。首先,我需要的时钟指针。创建自定义的时钟,我用自己的类,它扩展视图。时针和分针的PNG图像。
它们应位于屏幕的中心,但他们不。事实上,我甚至不能看到它们。这是个问题。

I searched the topic for several days, but finally confused. The idea is to create own alarm app with some special tricks. Firstly, I need clock hands. For creating custom clock, I used own class, which extends View. Hour and minute hands are PNG images. They should be located in the center of the screen, but they dont. Actually, I can't even see them. And that is the question.

下面是时钟类

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Point;
import android.graphics.drawable.Drawable;
//import android.os.Handler;
import android.text.format.Time;
import android.util.AttributeSet;
import android.view.Display;
import android.view.View;
import android.view.WindowManager;



@SuppressLint("NewApi")
public class Clock extends View {

public Clock(Context context) {
    super(context);
    // TODO Auto-generated constructor stub
}


private Drawable mHourHand;
private Drawable mMinuteHand;

private boolean mAttached;

static private float mMinutes;
static private float mHour;
private boolean mChanged;

Context mContext;
private boolean mSeconds;

// Gettes & setters. These clock must present alarm time which user sets in the next view

protected float getmMinutes() {
return mMinutes;
}

protected static void setmMinutes(float mMinutes) {
Clock.mMinutes = mMinutes;
}

protected float getmHour() {
return mHour;
}

protected static void setmHour(float mHour) {
Clock.mHour = mHour;
}


private Point size;

// ctors

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


public Clock(Context context, AttributeSet attrs,
        int defStyle) {
        super(context, attrs, defStyle);
        Resources r = context.getResources();
        TypedArray a =
        context.obtainStyledAttributes(attrs, R.styleable.AnalogClock, defStyle, 0);
        mContext=context;

        mHourHand = r.getDrawable(R.drawable.hours);

        mMinuteHand = r.getDrawable(R.drawable.minuts);
}



@Override
protected void onAttachedToWindow() {
    super.onAttachedToWindow();

    if (!mAttached) {
        mAttached = true;
        IntentFilter filter = new IntentFilter();

        filter.addAction(Intent.ACTION_TIME_TICK);
        filter.addAction(Intent.ACTION_TIME_CHANGED);
        filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);

     // getContext().registerReceiver(mIntentReceiver, filter, null, mHandler);
    }

 }

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {


    int desiredWidth = 150;  // and yes, 150 what? px, inches, dpi-s? I draw it just randomly
    int desiredHeight = 150;

    int widthMode = MeasureSpec.getMode(widthMeasureSpec);
    int widthSize = MeasureSpec.getSize(widthMeasureSpec);
    int heightMode = MeasureSpec.getMode(heightMeasureSpec);
    int heightSize = MeasureSpec.getSize(heightMeasureSpec);

    int width;
    int height;

    //Measure Width
    if (widthMode == MeasureSpec.EXACTLY) {
        //Must be this size
        width = widthSize;
    } else if (widthMode == MeasureSpec.AT_MOST) {
        //Can't be bigger than...
        width = Math.min(desiredWidth, widthSize);
    } else {
        //Be whatever you want
        width = desiredWidth;
    }

    //Measure Height
    if (heightMode == MeasureSpec.EXACTLY) {
        //Must be this size
        height = heightSize;
    } else if (heightMode == MeasureSpec.AT_MOST) {
        //Can't be bigger than...
        height = Math.min(desiredHeight, heightSize);
    } else {
        //Be whatever you want
        height = desiredHeight;
    }

    setMeasuredDimension(width, height);

}


@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    mChanged = true;
}




@SuppressWarnings({ "deprecation" })
@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    boolean changed = mChanged;
    if (changed) {
        mChanged = false;
    }

    boolean seconds = mSeconds;
    if (seconds ) {
        mSeconds = false;
    }

    int w = 100;  //These are too made randomly
    int h = 100;  

    WindowManager wm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
    Display display = wm.getDefaultDisplay();
   // if (android.os.Build.VERSION.SDK_INT <= 13)
   // {
        w = display.getWidth();  // deprecated
        h = display.getHeight();  // deprecated

    //}
   // else if (android.os.Build.VERSION.SDK_INT > 13)
    //{
        //size = null;
        //display.getSize(size);
        //w = size.x;
        //h = size.y;
    //}   ... I cant figure out, why, but size returns null. So I'll use deprecated ones just for     
     now.

    // **Here are my measures. I suggest that if height of an hour hand should be about 1/4 of   
       screen width, then following the proportion - width of that hand should be old width*new 
       height/old height, or smthng**   

    int sizeXHour = w/3;
        int sizeYHour = mHourHand.getIntrinsicHeight()*sizeXHour/mHourHand.getIntrinsicWidth();

        int xHour = sizeXHour/2;
        int yHour = sizeYHour/2;

        canvas.rotate(mHour / 12.0f * 360.0f, xHour, yHour);
        final Drawable hourHand = mHourHand;
        if (changed) {
        hourHand.setBounds((w / 2) - xHour, (h / 2) - yHour, sizeXHour, sizeYHour);
        }
        hourHand.draw(canvas);
        canvas.restore();

        int sizeYMinute = h/4;
        int sizeXMinute = mMinuteHand.getIntrinsicWidth()*sizeYMinute/mMinuteHand.getIntrinsicHeight();

        int xMinute = sizeXMinute/2;
        int yMinute = sizeYMinute/2;

        canvas.save();
        canvas.rotate(mMinutes / 60.0f * 360.0f, xMinute, yMinute);
        final Drawable minuteHand = mMinuteHand;
        if (changed) {
            minuteHand.setBounds((w / 2 - xMinute), (h / 2 - yMinute), sizeXMinute, sizeYMinute);
        }
        minuteHand.draw(canvas);
        canvas.restore();
        canvas.save();

}

我觉得有些地方是非常错误的,但找不出什么。 XML是:

I feel that something is very wrong, but can not figure what. The XML is:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="ee.st.running.dreamyclock.MainActivity"
android:background = "@drawable/clockk" >

<View
    android:id="@+id/view1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

<st.running.dreamyclock.Clock
    android:id="@+id/clock"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerHorizontal="true"
    android:layout_centerVertical = "true"
    android:layout_marginTop="124dp" />
</RelativeLayout>

在ATTRS是:

the attrs are:

  <?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="AnalogClock">
    <attr name="hand_hour" format="reference"/>
    <attr name="hand_minute" format="reference"/>
</declare-styleable>
</resources>

它是从哪里来的任何想法?谢谢

Any ideas where it came from? Thank you

推荐答案

是这样过工作吗?尝试将它添加到时钟构造函数:
setWillNotDraw(假);

Was this ever working? Try to add this to Clock constructor: setWillNotDraw(false);

如果这种观点并没有做自己的任何绘图,设置该标志允许进一步的优化。在默认情况下,这个标志没有被设置上查看,但可以在某些视图子类,如设置的ViewGroup。通常情况下,如果重写的onDraw(android.graphics.Canvas),你应该清除该标志。

"If this view doesn't do any drawing on its own, set this flag to allow further optimizations. By default, this flag is not set on View, but could be set on some View subclasses such as ViewGroup. Typically, if you override onDraw(android.graphics.Canvas) you should clear this flag."

编辑:
如果你想重新绘制你的看法,你应该叫无效()

无效整个视图。如果视图是可见的,的onDraw(android.graphics.Canvas)将在未来的某个时刻被调用。

"Invalidate the whole view. If the view is visible, onDraw(android.graphics.Canvas) will be called at some point in the future. "

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    mChanged = true;
    this.invalidate();
}

您甚至不必调用无效();如果你只是想例如旋转视图:

You don't even have to call invalidate(); if you just want to for example rotate the view:

 @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mChanged = true;
        setRotation(20);
    }

编辑2:

当你为一个可绘制设定界限,正确的值应大于左,例如更高:
minuteHand.setBounds(X - (W / 2),Y - (H / 2),X +(W / 2)+ 4,Y +(H / 4));
要么
minuteHand.setBounds(X - (W / 2)中,y - (H / 2)中,x +(W / 2)+ minuteHand.getIntrinsicWidth()中,y +(H / 4));

When you are setting bounds for a Drawable, the "right" value should be higher than "left" for example: minuteHand.setBounds(x - (w / 2), y - (h / 2), x + (w / 2) + 4, y + (h / 4)); or minuteHand.setBounds(x - (w / 2), y - (h / 2), x + (w / 2) + minuteHand.getIntrinsicWidth(), y + (h / 4));

这篇关于规模和对齐定制的Andr​​oid AnalogClock手的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆