[英]canvas.scale() not working properly
I have the following code, that when I pinch in the screen it will join/split the objects. 我有以下代码,当我捏屏幕时,它将连接/拆分对象。
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.View;
import android.view.ScaleGestureDetector.SimpleOnScaleGestureListener;
import android.view.animation.ScaleAnimation;
import android.widget.RelativeLayout;
public class GDTicketGroupView extends RelativeLayout{
//Constants
int kNumberofTickets = 3;
int kTicketWidth = 225;
int kTicketHeight = 100;
int kMarginLeft = 12;
int kMarginTop = 12;
int kMarginRight = 12;
int kMarginBottom = 12;
float kMinScale = 0.5f;
float kNormalScale = 1.0f;
float kMaxScale = 1.2f;
//Variables
float mScaleFactor = 1;
Boolean scaling = false;
RelativeLayout gestureview;
//Temporary
float tmpScale = 1;
//Objects
ScaleGestureDetector scaleGestureDetector;
GDTicketView Ticket;
public GDTicketGroupView(Context context) {
super(context);
//Creating the GestureDetector
scaleGestureDetector = new ScaleGestureDetector(context, new simpleOnScaleGestureListener());
//Gesture View
gestureview = new RelativeLayout(context);
RelativeLayout.LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
gestureview.setLayoutParams(params);
//Adding SubViews
addTickets(context);
//Only for Testing
setBackgroundColor(Color.RED);
}
public GDTicketGroupView(Context context, AttributeSet attrs) {
super(context, attrs);
//Creating the GestureDetector
scaleGestureDetector = new ScaleGestureDetector(context, new simpleOnScaleGestureListener());
//Adding SubViews
addTickets(context);
//Only for Testing
setBackgroundColor(Color.RED);
}
public GDTicketGroupView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
//Creating the GestureDetector
scaleGestureDetector = new ScaleGestureDetector(context, new simpleOnScaleGestureListener());
//Adding SubViews
addTickets(context);
//Only for Testing
setBackgroundColor(Color.RED);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
scaleGestureDetector.onTouchEvent(event);
return true;
}
@Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.save();
if (scaling == true){
if (mScaleFactor >= kMinScale * tmpScale && mScaleFactor < kMaxScale * tmpScale){
canvas.scale(kNormalScale, mScaleFactor);
Log.d("DEBUG", "mScaleFactor >= kMinScale * tmpScale && mScaleFactor < kMaxScale * tmpScale"+" is True");
}
}
canvas.restore();
Log.d("DEBUG", "onDraw is running");
}
public class simpleOnScaleGestureListener extends SimpleOnScaleGestureListener {
@Override
public boolean onScale(ScaleGestureDetector detector) {
mScaleFactor = detector.getScaleFactor();
Log.d("DEBUG", "mScaleFactor is "+mScaleFactor+", so Scale is Running");
scaling = true;
invalidate();
return true;
}
@Override
public void onScaleEnd(ScaleGestureDetector detector) {
//Expand Animation
if (mScaleFactor >= kMinScale){
ScaleAnimation anim = new ScaleAnimation(1, 1, 1, 1);
startAnimation(anim);
tmpScale=1;
adjustTickets();
} else if (mScaleFactor < kMinScale){
ScaleAnimation anim = new ScaleAnimation(1, 1, mScaleFactor, 1);
startAnimation(anim);
tmpScale = kMinScale;
adjustTickets();
}
scaling = false;
Log.d("DEBUG", "Scale have ended");
}
}
public void adjustTickets(){
//First Ticket
GDTicketView firstTicket = (GDTicketView)findViewWithTag(1);
//Last Ticket
GDTicketView lastTicket = (GDTicketView)findViewWithTag(kNumberofTickets);
// Creating average variables
int totalY = firstTicket.getTop() + lastTicket.getTop();
int parcialY = totalY / (kNumberofTickets - 1);
// The rest of the tickets
for (int i = 2; i <= kNumberofTickets - 1; i++) {
GDTicketView ticketBeingAdjusted = (GDTicketView)findViewWithTag(i);
RelativeLayout.LayoutParams params = new LayoutParams(kTicketWidth, kTicketHeight);
params.setMargins(kMarginLeft, (i - 1) * parcialY, kMarginRight, kMarginBottom);
ticketBeingAdjusted.setLayoutParams(params);
}
}
public void addTickets(Context context){
for(int i = 1; i <= kNumberofTickets; i++){
Ticket = new GDTicketView(context);
RelativeLayout.LayoutParams params = new LayoutParams(kTicketWidth, kTicketHeight);
params.setMargins(kMarginLeft, kMarginTop, kMarginRight, kMarginBottom);
params.addRule(CENTER_HORIZONTAL);
if (i != 1){
params.setMargins(kMarginLeft, kMarginTop+kTicketHeight, kMarginRight, kMarginBottom);
GDTicketView ticket = (GDTicketView)findViewWithTag(i-1);
if (ticket.getId() == View.NO_ID){
ticket.setId(i);
}
params.addRule(RelativeLayout.ALIGN_TOP, ticket.getId());
}
Ticket.setTag(i);
Ticket.setBackgroundColor(Color.GREEN);
Log.d("INIT", "Ticket View " + i +" added correctly");
addView(Ticket, params);
}
}
}
In the onDraw method, whan the mScaleFactor change, the view don't change the height, but in the logcat mScaleFactor it's not 1 so, I think that something don't work right. 在onDraw方法中,更改了mScaleFactor,视图没有更改高度,但是在logcat mScaleFactor中,它不是1,所以我认为有些事情行不通。
You call these methods in order: 您可以依次调用以下方法:
save()
scale()
restore()
But you don't draw anything after calling scale()
. 但是在调用
scale()
之后,您什么都不会绘制。 Your code changes the scale factor and then restores it back to the original scale factor of 1,1. 您的代码将更改比例因子,然后将其恢复为原始比例因子1,1。
I see that you also use two ScaleAnimation
instances. 我看到您还使用了两个
ScaleAnimation
实例。 One doesn't do anything since it scales from 1,1 to 1,1. 因为它从1,1缩放到1,1,所以它什么也没做。 The other one should work though.
另一个应该可以。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.