Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/225.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在自定义时钟指针中缩放和对齐_Java_Android_Scaling_Clock - Fatal编程技术网

Java 在自定义时钟指针中缩放和对齐

Java 在自定义时钟指针中缩放和对齐,java,android,scaling,clock,Java,Android,Scaling,Clock,我找了好几天这个话题,但最后还是弄糊涂了。这个想法是用一些特殊的技巧创建自己的报警应用程序。首先,我需要时钟指针。为了创建自定义时钟,我使用了自己的类,它扩展了视图。时针和分针是PNG图像。 它们应该位于屏幕中央,但它们不在。事实上,我甚至看不见他们。这就是问题所在 这是钟表课 import android.annotation.SuppressLint; import android.content.Context; import android.content.Intent; import

我找了好几天这个话题,但最后还是弄糊涂了。这个想法是用一些特殊的技巧创建自己的报警应用程序。首先,我需要时钟指针。为了创建自定义时钟,我使用了自己的类,它扩展了视图。时针和分针是PNG图像。 它们应该位于屏幕中央,但它们不在。事实上,我甚至看不见他们。这就是问题所在

这是钟表课

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是:

<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>
这些属性是:

  <?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>

知道它是从哪里来的吗?谢谢

这有用吗?尝试将此添加到时钟构造函数: setWillNotDrawfalse

如果此视图本身不进行任何绘图,请设置此标志以允许进一步优化。默认情况下,此标志不在视图上设置,但可以在某些视图子类(如ViewGroup)上设置。通常,如果覆盖onDrawandroid.graphics.Canvas,则应清除此标志

编辑: 如果要重新绘制视图,应该调用invalidate方法

使整个观点无效。如果视图可见,将来某个时候将调用onDrawandroid.graphics.Canvas

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    mChanged = true;
    this.invalidate();
}
你甚至不需要调用invalidate;例如,如果只想旋转视图:

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

设置绘图边界时,右值应高于左值,例如: minuteHand.setBoundsx-w/2,y-h/2,x+w/2+4,y+h/4; 或
minuteHand.setBoundsx-w/2,y-h/2,x+w/2+minuteHand.getIntrinsicWidth,y+h/4

它工作了,但没有时钟。它只是显示了第一层的图片。以前它的工作原理很奇怪,当左上角有一个箭头时,这两个可拖动部件是否都可见?不,不幸的是,我添加了无效,但它们没有出现。可能是错误的维度,现在我将尝试设置一些随机值,比如150和150,但它们也不起作用。这只意味着代码中的某些内容完全错误或缺失。但是仍然找不到它…再次否定的是,可能对arrts.xml和styleable有一些干扰,但我认为没有它它它将无法工作