How to resize my widgets by ratio in android - java

I want to resize my widgets in the layout by ratio, but I can't.
At time I resizing ViewPager or com.daimajia.slider.SliderLayout by ratio and Measure, but childs of ViewPager or com.daimajia.slider.SliderLayout lose their height.
I create a custom widget for this work.
Code example for ImageView:
package ...;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
public class SquareImageView extends android.support.v7.widget.AppCompatImageView {
public SquareImageView(Context context) {
super(context);
}
public SquareImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SquareImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = getMeasuredWidth();
setMeasuredDimension(width, width);
}
#Override
protected void onDraw(Canvas canvas) {
Drawable drawable = getDrawable();
if (drawable == null) {
return;
}
int w = 0, h = 0;
if (getWidth() == 0 || getHeight() == 0) {
if (getMeasuredWidth() == 0 || getMeasuredHeight() == 0) {
return;
}
else {
w = getMeasuredWidth();
h = getMeasuredHeight();
}
return;
}
else {
w = getWidth();
h = getHeight();
}
Bitmap b = ((BitmapDrawable) drawable).getBitmap();
Bitmap bitmap = b.copy(Bitmap.Config.ARGB_8888, true);
final Rect rect = new Rect(0, 0, w, w);
Bitmap roundBitmap = getCroppedBitmap(bitmap, w);
canvas.drawBitmap(roundBitmap, rect, rect, null);
}
public static Bitmap getCroppedBitmap(Bitmap bmp, int radius) {
Bitmap sbmp;
if (bmp.getWidth() != radius || bmp.getHeight() != radius) {
float smallest = Math.min(bmp.getWidth(), bmp.getHeight());
float factor = smallest / radius;
sbmp = Bitmap.createScaledBitmap(bmp,
(int) (bmp.getWidth() / factor),
(int) (bmp.getHeight() / factor), false);
} else {
sbmp = bmp;
}
Bitmap output = Bitmap.createBitmap(radius, radius, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final String color = "#BAB399";
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, radius, radius);
paint.setAntiAlias(true);
paint.setFilterBitmap(true);
paint.setDither(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(Color.parseColor(color));
canvas.drawCircle(radius / 2 + 0.7f, radius / 2 + 0.7f,
radius / 2 + 0.1f, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(sbmp, rect, rect, paint);
return output;
}
}
My Codes not worked for this widgets:
ViewPager, com.daimajia.slider.SliderLayout.
//--------------------------------------------------------
//--------------------------------------------------------
//------------> ***** Answer - Go Down ***** <------------
//--------------------------------------------------------
//------------> ***** Answer - Go Down ***** <------------
//--------------------------------------------------------
//------------> ***** Answer - Go Down ***** <------------
//--------------------------------------------------------
//--------------------------------------------------------
I found the answer my question.
public class ViewPagerByRatioSize extends ViewPager {
Integer layout_ratioX = 0, layout_ratioY = 0;
public ViewPagerByRatioSize(Context context) {
super(context);
}
public ViewPagerByRatioSize(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ViewPagerByRatioSize, 0, 0);
try {
layout_ratioX = typedArray.getInteger(R.styleable.ViewPagerByRatioSize_layout_ratioXViewPager, 0);
layout_ratioY = typedArray.getInteger(R.styleable.ViewPagerByRatioSize_layout_ratioYViewPager, 0);
}
finally {
typedArray.recycle();
}
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
int width = getMeasuredWidth();
super.setMeasuredDimension(width, width / layout_ratioX * layout_ratioY);
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(width / layout_ratioX * layout_ratioY, MeasureSpec.AT_MOST));
}
}
This code worked for me, but I change codes because my application can't get values from xml codes.
This new codes:
public class ViewPagerByRatioSize extends ViewPager {
public ViewPagerByRatioSize(Context context) {
super(context);
}
public ViewPagerByRatioSize(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
int width = getMeasuredWidth();
super.setMeasuredDimension(width, width / 3 * 2);
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(width / 3 * 2, MeasureSpec.AT_MOST));
}
}
Successful for ever :)

Related

android - Canvas draw path on canvas without touch direction

I build this class to draw on screen to implement some brushes created via differents Paints and paths.
Currently is drawing a square based on user touch movement, but the draw path is being rotated by the draw direction of the touch. I tried to apply a rect without no luck and I don't found any related info about this phenom
EDIT :
This image is from current result
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.MotionEvent;
public class RachetBasic extends androidx.appcompat.widget.AppCompatImageView {
private Canvas canvas;
private Bitmap bitmap;
private Paint bitmapPaint = new Paint(Paint.DITHER_FLAG);
private Path squarePath = new Path();
private Paint squarePaint = new Paint();
public RachetBasic(Context context) {
super(context);
}
public RachetBasic(Context context, AttributeSet attrs) {
super(context, attrs);
}
public RachetBasic(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#Override
protected void onSizeChanged(int width, int height, int oldw, int oldh) {
super.onSizeChanged(width, height, oldw, oldh);
squarePaint.setAntiAlias(true);
squarePaint.setDither(true);
squarePaint.setStyle(Paint.Style.STROKE);
squarePaint.setStrokeCap(Paint.Cap.SQUARE);
squarePaint.setStrokeWidth(80);
squarePaint.setColor(Color.BLUE);
bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
canvas = new Canvas(bitmap);
}
#Override
protected void onDraw(Canvas canvas) {
canvas.drawBitmap(bitmap, 0, 0, bitmapPaint);
canvas.drawPath(squarePath, squarePaint);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
if (event.getAction() == MotionEvent.ACTION_DOWN) {
squarePath.moveTo(x, y);
} else if (event.getAction() == MotionEvent.ACTION_MOVE) {
squarePath.lineTo(x, y);
} else if (event.getAction() == MotionEvent.ACTION_UP) {
squarePath.lineTo(x, y);
canvas.drawPath(squarePath, squarePaint);
squarePath.reset();
}
invalidate();
return true;
}
}
public class MainActivity extends androidx.appcompat.app.AppCompatActivity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new RachetBasic(MainActivity.this));
}
}

Draw a circle onto a view (android)

I am starting with my first attempts to write an android app. I'd like to to visualize the Monte-Carlo-Approximation for pi. Hence I first want to draw a Circle onto a view but i dont get it working!
I have tried to create my own "CircleView" Class which extends "View" and overwrite the onDraw(..) method like its explained over here: How to draw circle by canvas in Android?
This is my CircleView Class
public class CircleView extends View {
public CircleView(Context context) {
super(context);
}
protected void onDraw(Canvas canvas){
super.onDraw(canvas);
Paint paint = new Paint();
paint.setColor(150);
canvas.drawCircle(50,50,20,paint);
}
}
I have inserted the CircleView into a LinearLayout with the following XML-code
<com.tak3r07.montecarlopi.CircleView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/circleView"
android:layout_weight="1"/>
(Btw Android Studio is telling me in the XML-view at the right side: "Rendering Problems Custom view CircleView is not using the 2- or 3-argument View constructors; XML attributes will not work")
The App just crashes with the following log: http://pastebin.com/Gv1GaHtX
Can someone tell what i did wrong?
I thought this setup would create an activity with a view which displays a circle.
Regards
Edit: Crash is fixed by adding the 2 and 3 Parameter Constructor in CircleView (See https://stackoverflow.com/a/13797457/3248708)
But now i still do not see any Circle in the activity
A couple of observations:
You need to take into account the width and height assigned to your view when determining your circle's center point and radius.
You should take into account the padding assigned to your View so you don't draw in that reserved portion.
You should avoid allocating objects within your onDraw method since this gets called a lot.
In order to allow your view to be specified in an XML layout, you need to provide the constructor that takes a Context and an AttributeSet. The AttributeSet is the mechanism by which your XML attributes are passed to your view.
Give this a try:
package com.tak3r07.montecarlopi;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
public class CircleView extends View
{
private static final int DEFAULT_CIRCLE_COLOR = Color.RED;
private int circleColor = DEFAULT_CIRCLE_COLOR;
private Paint paint;
public CircleView(Context context)
{
super(context);
init(context, null);
}
public CircleView(Context context, AttributeSet attrs)
{
super(context, attrs);
init(context, attrs);
}
private void init(Context context, AttributeSet attrs)
{
paint = new Paint();
paint.setAntiAlias(true);
}
public void setCircleColor(int circleColor)
{
this.circleColor = circleColor;
invalidate();
}
public int getCircleColor()
{
return circleColor;
}
protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
int w = getWidth();
int h = getHeight();
int pl = getPaddingLeft();
int pr = getPaddingRight();
int pt = getPaddingTop();
int pb = getPaddingBottom();
int usableWidth = w - (pl + pr);
int usableHeight = h - (pt + pb);
int radius = Math.min(usableWidth, usableHeight) / 2;
int cx = pl + (usableWidth / 2);
int cy = pt + (usableHeight / 2);
paint.setColor(circleColor);
canvas.drawCircle(cx, cy, radius, paint);
}
}
You can create a Circular layout and inside this view, every childs should be rounded up :
public class CircleView extends FrameLayout {
private Bitmap maskBitmap;
private Paint paint, maskPaint;
public CircleView(Context context) {
super(context);
init();
}
public CircleView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public CircleView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
#RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public CircleView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init();
}
private void init() {
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
maskPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
maskPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
setWillNotDraw(false);
}
#Override
public void draw(Canvas canvas) {
Bitmap offscreenBitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
Canvas offscreenCanvas = new Canvas(offscreenBitmap);
super.draw(offscreenCanvas);
if (maskBitmap == null) {
maskBitmap = createMask(getWidth(), getHeight());
}
offscreenCanvas.drawBitmap(maskBitmap, 0f, 0f, maskPaint);
canvas.drawBitmap(offscreenBitmap, 0f, 0f, paint);
}
private Bitmap createMask(int width, int height) {
Bitmap mask = Bitmap.createBitmap(width, height, Bitmap.Config.ALPHA_8);
Canvas canvas = new Canvas(mask);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(Color.WHITE);
canvas.drawRect(0, 0, width, height, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
canvas.drawRoundRect(new RectF(0, 0, width, height), width/2f, height/2f, paint);
return mask;
}
}

How to maintain quality of the image downloaded from url to imageview and crop them to a circle?

I am using the following code with the help of 'Android Universal image loader' library, but the quality of the image is very poor and I get too many skipped frames in my logcat,
here is my code, please look and help how can I improve it?
private class DownloadImageTask extends AsyncTask<String, Void,
Bitmap> {
ImageView bmImage;
public DownloadImageTask(ImageView bmImage) {
this.bmImage = bmImage;
}
protected Bitmap doInBackground(String... urls) {
String urldisplay = urls[0];
// Bitmap mIcon11 = null;
ImageLoader imageLoader = ImageLoader.getInstance();
Bitmap bitmap = imageLoader.loadImageSync(urldisplay);
Bitmap circleBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(),
Bitmap.Config.ARGB_8888);
BitmapShader shader = new BitmapShader(bitmap, TileMode.CLAMP, TileMode.CLAMP);
Paint paint = new Paint();
paint.setShader(shader);
Canvas c = new Canvas(circleBitmap);
c.drawCircle(bitmap.getWidth() / 2, bitmap.getHeight() / 2, bitmap.getWidth() / 2, paint);
//img1.setImageBitmap(circleBitmap);
//bmImage.setImageBitmap(circleBitmap);
return circleBitmap;
}
protected void onPostExecute(Bitmap result) {
bmImage.setImageBitmap(result);
}
}
Picasso and Volley are very good for images, I use Volley and I made a class that extends NetworkImageView and there I crop the image and make it round.
public class RoundedNetworkImageView extends NetworkImageView {
private Bitmap frame;
public RoundedNetworkImageView(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
public RoundedNetworkImageView(Context context, AttributeSet attrs) {
super(context, attrs);
// frame = BitmapFactory.decodeResource(context.getResources(), R.drawable.chat_list_profile_frame);
}
public RoundedNetworkImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// frame = BitmapFactory.decodeResource(context.getResources(), R.drawable.chat_list_profile_frame);
}
#Override
protected void onDraw(Canvas canvas) {
// super.onDraw(canvas);
Drawable drawable = getDrawable();
if (drawable == null) {
return;
}
if (getWidth() == 0 || getHeight() == 0) {
return;
}
Bitmap b = ((BitmapDrawable) drawable).getBitmap();
if (b != null) {
Bitmap bitmap = b.copy(Bitmap.Config.ARGB_8888, true);
int w = getWidth(), h = getHeight();
Bitmap roundBitmap = getCroppedBitmap(bitmap, w);
canvas.drawBitmap(roundBitmap, 0, 0, null);
// canvas.drawBitmap(frame, 0, 0, null);
}
}
public static Bitmap getCroppedBitmap(Bitmap bmp, int radius) {
Bitmap sbmp;
if (bmp.getWidth() != radius || bmp.getHeight() != radius)
sbmp = Bitmap.createScaledBitmap(bmp, radius, radius, false);
else
sbmp = bmp;
Bitmap output = Bitmap.createBitmap(sbmp.getWidth(), sbmp.getHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final int color = 0xffa19774;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, sbmp.getWidth(), sbmp.getHeight());
paint.setAntiAlias(true);
paint.setFilterBitmap(true);
paint.setDither(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(Color.parseColor("#FFFFFF"));
canvas.drawCircle(sbmp.getWidth() / 2 + 0.7f, sbmp.getHeight() / 2 + 0.7f, sbmp.getWidth() / 2 + 0.1f, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(sbmp, rect, rect, paint);
return output;
}
}
//--------- and when I am using it public
// declaration
public RoundedNetworkImageView user_status_pic;
// getting the image from the url in an list adapter
viewHolder.user_status_pic.setImageUrl(image_url, imageLoader);
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Paint;
import com.squareup.picasso.Transformation;
public class CircleTransform implements Transformation {
#Override
public Bitmap transform(Bitmap source) {
int size = Math.min(source.getWidth(), source.getHeight());
int x = (source.getWidth() - size) / 2;
int y = (source.getHeight() - size) / 2;
Bitmap squaredBitmap = Bitmap.createBitmap(source, x, y, size, size);
if (squaredBitmap != source) {
source.recycle();
}
Bitmap bitmap = Bitmap.createBitmap(size, size, source.getConfig());
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint();
BitmapShader shader = new BitmapShader(squaredBitmap, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP);
paint.setShader(shader);
paint.setAntiAlias(true);
float r = size/2f;
canvas.drawCircle(r, r, r, paint);
squaredBitmap.recycle();
return bitmap;
}
#Override
public String key() {
return "circle";
}
}
try like this:
Picasso.with(context).load("url").transform(new CircleTransform()).into(target);

Image not resizing correctly on android

I'm having trouble with a library I got from the GitHub.
The Library leads to round an image. The rounding part works very well, but the image resizing doesn't do as great as the rest. It differs from image to image and I'd like to make this work to resize any image to the size of my View on android. For example, if I call this with android:layout_width="100dp" , I'd like to the image to be resized that much.
Thank you very much for your time.
This is the library:
package com.roundimage.support;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.provider.MediaStore;
import android.util.AttributeSet;
import android.widget.ImageView;
public class CircularImageView extends ImageView {
private int borderWidth = 3;
private int viewWidth;
private int viewHeight;
private Bitmap image;
private Paint paint;
private Paint paintBorder;
private BitmapShader shader;
public CircularImageView(Context context) {
super(context);
setup();
}
public CircularImageView(Context context, AttributeSet attrs) {
super(context, attrs);
setup();
}
public CircularImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setup();
}
private void setup()
{
// init paint
paint = new Paint();
paint.setAntiAlias(true);
paintBorder = new Paint();
setBorderColor(Color.WHITE);
paintBorder.setAntiAlias(true);
}
public void setBorderWidth(int borderWidth)
{
this.borderWidth = borderWidth;
this.invalidate();
}
public void setBorderColor(int borderColor)
{
if(paintBorder != null)
paintBorder.setColor(borderColor);
this.invalidate();
}
private void loadBitmap()
{
BitmapDrawable bitmapDrawable = (BitmapDrawable) this.getDrawable();
if(bitmapDrawable != null)
image = bitmapDrawable.getBitmap();
}
#SuppressLint("DrawAllocation")
#Override
public void onDraw(Canvas canvas)
{
//load the bitmap
loadBitmap();
// init shader
if(image !=null)
{
shader = new BitmapShader(Bitmap.createScaledBitmap(image, canvas.getWidth(), canvas.getHeight(), false), Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
paint.setShader(shader);
int circleCenter = viewWidth / 2;
// circleCenter is the x or y of the view's center
// radius is the radius in pixels of the cirle to be drawn
// paint contains the shader that will texture the shape
canvas.drawCircle(circleCenter + borderWidth, circleCenter + borderWidth, circleCenter + borderWidth, paintBorder);
canvas.drawCircle(circleCenter + borderWidth, circleCenter + borderWidth, circleCenter, paint);
}
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
int width = measureWidth(widthMeasureSpec);
int height = measureHeight(heightMeasureSpec, widthMeasureSpec);
viewWidth = width - (borderWidth *2);
viewHeight = height - (borderWidth*2);
setMeasuredDimension(width, height);
}
private int measureWidth(int measureSpec)
{
int result = 0;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
if (specMode == MeasureSpec.EXACTLY) {
// We were told how big to be
result = specSize;
} else {
// Measure the text
result = viewWidth;
}
return result;
}
private int measureHeight(int measureSpecHeight, int measureSpecWidth) {
int result = 0;
int specMode = MeasureSpec.getMode(measureSpecHeight);
int specSize = MeasureSpec.getSize(measureSpecHeight);
if (specMode == MeasureSpec.EXACTLY) {
// We were told how big to be
result = specSize;
} else {
// Measure the text (beware: ascent is a negative number)
result = viewHeight;
}
return result;
}
}
This is how I call it on XML:
<com.roundimage.support.CircularImageView
android:id="#+id/item_pic"
android:layout_width="70dp"
android:layout_height="70dp"
android:src="#drawable/example_id" />
How this stays like:
And how the image really is:
And for different images with different sizes, for different devices with diferent resolution, the image appear in a different way..
Ok, your code should work well, But it put image in image view without resize to fit in viewer, because you had these results.
Try adding this in layout:
android:scaleType="fitCenter"
Read mode about this in this tutorial: http://www.peachpit.com/articles/article.aspx?p=1846580&seqNum=2
Try using scaleType in the xml to be fitXY
android:ScaleType = "fitXY"
Or programmatically
imageview.setScaleType (ScaleType.FITXY)
If it doesn't work try another scaletype.
EDIT: See this post here.
#youssefhassan link points it out correctly:
You have to resize your image bitmap to desired size:
`
private void loadBitmap()
{
BitmapDrawable bitmapDrawable = (BitmapDrawable) this.getDrawable();
if(bitmapDrawable != null) {
int size = getPixelsFromDp(70);
Bitmap imageRealSize = bitmapDrawable.getBitmap();
image = Bitmap.createScaledBitmap(imageRealSize, size, size, true);
}
}
`
Where 'getPixelsFromDp' is a function to get dp's you added on xml in pixels (you can find load of pages to get its implementation)

Cannot pinch zoom if both fingers touch screen simultaneously

I have implemented zoom on my custom made view which draws a grid onto a canvas, but the zooming won't work if I put both fingers on the screen simultaneously. I have to first put one, then the other.
I followed this blog post by Adam Powell to implement zoom, and made this custom view:
public class ZoomView extends View{
private float width;
private float height;
Paint lineColor;
Paint bgColor;
private float mScaleFactor;
private ScaleGestureDetector scaleDetector;
public CanvasView(Context context) {
super(context);
setFocusable(true);
setFocusableInTouchMode(true);
lineColor = new Paint();
lineColor.setColor(getResources().getColor(R.color.white));
bgColor = new Paint();
bgColor.setColor(getResources().getColor(R.color.black));
mScaleFactor = 1;
mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh){
width = w/9;
height = h/9;
super.onSizeChanged(w,h,oldw,oldh);
}
#Override
protected void onDraw(Canvas canvas){
super.onDraw(canvas);
canvas.save();
canvas.scale(mScaleFactor, mScaleFactor); //for zooming
for(int i=0; i <= 9; i++){
canvas.drawLine(0,i*height, 9*width,i*height,lineColor);
canvas.drawLine(i*width, 0, i*width, 9*height, lineColor);
}
canvas.restore();
}
#Override
public boolean onTouchEvent(MotionEvent ev){
mScaleDetector.onTouchEvent(ev);
return true;
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
setMeasuredDimension(800, 1000);
}
private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
#Override
public boolean onScale(ScaleGestureDetector detector) {
mScaleFactor *= detector.getScaleFactor();
// Don't let the object get too small or too large.
mScaleFactor = Math.max(0.1f, Math.min(mScaleFactor, 5.0f));
invalidate();
return true;
}
}
}
So why is the zooming behaving this way?
Any help would be greatly appreciated. Thanks!
This may look like a silly question, but does the multi touch behavior work on other apps (Maps for example) at this device?
I've tested your code (with minor changes, see below) on an LG Optimus Black, Android 4.0.3, and it worked, both fingers simultaneously.
package com.example.teste;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.View;
public class ZoomView extends View {
private float width;
private float height;
Paint lineColor;
Paint bgColor;
private float mScaleFactor;
private ScaleGestureDetector mScaleDetector;
public ZoomView(Context context) {
super(context);
setFocusable(true);
setFocusableInTouchMode(true);
lineColor = new Paint();
lineColor.setColor(getResources().getColor(R.color.ics_blue_bright));
bgColor = new Paint();
bgColor.setColor(getResources().getColor(R.color.black));
mScaleFactor = 1;
mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
width = w / 9;
height = h / 9;
super.onSizeChanged(w, h, oldw, oldh);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.save();
canvas.scale(mScaleFactor, mScaleFactor); // for zooming
for (int i = 0; i <= 9; i++) {
canvas.drawLine(0, i * height, 9 * width, i * height, lineColor);
canvas.drawLine(i * width, 0, i * width, 9 * height, lineColor);
}
canvas.restore();
}
#Override
public boolean onTouchEvent(MotionEvent ev) {
mScaleDetector.onTouchEvent(ev);
return true;
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(800, 1000);
}
private class ScaleListener extends
ScaleGestureDetector.SimpleOnScaleGestureListener {
#Override
public boolean onScale(ScaleGestureDetector detector) {
mScaleFactor *= detector.getScaleFactor();
// Don't let the object get too small or too large.
mScaleFactor = Math.max(0.1f, Math.min(mScaleFactor, 5.0f));
invalidate();
return true;
}
}
}

Categories

Resources