We developing custom textview that zoom in/out depends on pinch gesture, and able to resize textview and scale text. But, when zoom out this view, text are cropped unintentionally.
We write a code like this.
1.Get scaled value in gesture listener and postScale in onDraw()
2.Calculate new view size by layout(int, int, int, int)
#Override
public void onDraw(Canvas canvas) {
android.graphics.Matrix m = new android.graphics.Matrix();
m.postScale(mScaleFactor, mScaleFactor);
canvas.concat(m);
layout((int) l, (int) t, (int)r , (int) b );
super.onDraw(canvas);
}
This is may not be perfect solution for you,But you can try it.
1)Detect the pinch gesture
2)calculate the Scale factor(you can do it manually or you can use ScaleDetector class)
3)Use LayoutParams to actually resize your textview.
4)however it will not scale the text size but you can do it programatically respective to your scale gesture.
If you have any question feel free to comment,I have done it before with slightly different requirement.
Related
I'm making a custom View thats derived from an ImageViewand I control where the image has to be within this ImageView using padding.
I have set OnClickListener on my custom ImageView that resizes it:
image.setOnClickListener(new ImageView.OnClickListener(){
#Override
public void onClick(View v) {
image.resize_image();
}
});
and this is how this function is looking like
public void resize_image(){
ViewGroup.LayoutParams params = getLayoutParams();
params.height = new_heigth;
params.width = new_width;
setLayoutParams(params);
}
After this resizing is done I don't want my displayed image to change size (only the custom ImageView is changing size so I can draw an extra stuff around this image) within my custom ImageView so inside onDraw(Canvas) member function I set the new padding
class custom_ImageView extends ImageView{
//...
#Override
protected void onDraw(Canvas canvas) {
//...
setPadding(new_left_padding, new_top_padding, new_right_padding, new_bottom_padding);
//...
}
//...
}
Result is that width and heigth are changed like I wanted but my displayed image is neither in the right position or size.
Interesting this is that if I add an extra line of invalidate(); in the end of my resize_image() and I click on my custom_ImageView twice - on the 2nd click image draws itself in right size and position like I wanted.
Can anyone tell me why this is happening?
I kind of worked around this by not using ImageView at all but just drawing image where it needs to be by using Canvas.drawBitmap(Bitmap, RectF, RectF, Paint)
This way I don't have to specify images location using setPadding within onDraw, but I can do it simply by specifying position using RectF.
I want to divide the image into sub images and when I click on a part of the image will give me the name of the region, for example, this is my question how to recognize a region from the image, or how to divide the image into sub-images and use it in imageViews
And thank you in advance
In my opinion #fractalwrench's idea is quite good for your case. Basic steps are listed below.
Subclass Android ImageView. For example, MultiRegionImageView.
Override its onTouchEvent method. (This method gets called whenever user touches the view)
User touches the image and thereby onTouchEvent is called and provides the exact touch point (x, y).
Declare another method or interface which determines at which region a given point is. For example, getRegionByPoint(int x, int y)
If you would like to highlight that region boundaries, you could use paths. First off, you should define paths and save them into a raw file (XML, for example), then using region ID, fetch its path and finally draw that path over the main image.
For drawing a path over the main image, you should also override onDraw method of ImageView class and use canvas.drawPath();
public class MultiRegionImageView extends ImageView {
RegionProvider mRegionProvider;
int mId = -1;
private Paint mPaint;
public MultiRegionImageView(Context context) {
super(context);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
mId = mRegionProvider.getRegionIdByPoint(event.getX(), event.getY());
return super.onTouchEvent(event);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if(mId != -1) {
canvas.drawPath(mRegionProvider.getRegionBoundaryPath(mId), mPaint);
}
}
public interface RegionProvider{
int getRegionIdByPoint(float x, float y);
Path getRegionBoundaryPath(int id);
}
}
You should only need one ImageView to display the map. If you override onTouchEvent(MotionEvent e), you can get the position which is being touched in the View. If you store the position and shape of each region in some sort of List, you can check whether a touch event is within a region (and display whatever text you need to).
I have drawn a bitmap image over a canvas.
Bitmap image = BitmapFactory.decodeResource(getResources(), R.drawable.sq);
canvas.drawColor(color.black);
Rect dstRectForRender = new Rect(0,0,320,450);
canvas.drawBitmap(image, null,dstRectForRender,null);
The image gets displayed based on my screnn on a cnavs.
On my touch input, I need to pass the x and y co-ordinate position of the image and fill that pixel with a color to show that the image is painted on a drag event.
How can I pass the x and y coo-ordinate parameters? Which functions should I use to plot the pixels on the image?
I appreciate your help and sweet time.
I'm not sure if this is the best way to do this, but it would be much easier to do this if you defined your own subclass of ImageView and name it something like DrawableImageView. You'd have to make sure you implement all the basic constructors from ImageView, then override the onTouchEvent method. From that event you can get the touch coordinates and store them in an ArrayList<Point> and use that ArrayList by overriding the onDraw method and "painting" the image.
public class DrawableImageView extends ImageView {
ArrayList<Point> list = new ArrayList<Point>();
//constructors..
#Override
public boolean onTouchEvent (MotionEvent event) {
float x = event.getX();
float y = event.getY();
list.add(new Point(x,y));
invalidate();
}
This is just a very brief overview of how to start your class, and may not be the most accurate way of doing things (depending on your specific code). Now, instead of using <ImageView> tags in your xml (or, loading an ImageView programatically), you refer to your subclass like so:
<your.package.name.DrawableImageView
/>
Edit
In response to your comment, there is no predetermined way to draw over an image. You must implement this yourself, which is why I recommended storing Points in an ArrayList. I'm not really sure what you're trying to achieve here, but to draw (for example) black dots over an image you have to override onDraw:
public void onDraw(Canvas c) {
super.onDraw(c);
for(Point p : list) {
//Draw black point at x and y.. I'm posting from my cell so I can't go into much detail
}
}
Also, to force a View to redraw itself you need to use the invalidate() method in your onTouchEvent() (which I've added above).
Greets ,
How can I get the Coordinates of the Bitmap not of the screen. Screen Coordinates got by event.getX(),event.getY() methods but not getting coordinates of the bitmap. Please help anyone.
You can't get the coordinates of the bitmap directly. You need to calculate to yourself.
Use the position of the ImageView, and with that you can handle it.
Of course, when you are after Activity onCreate you can acces to any inflated (active) views parameter.
Exemple.
ImageView a;
a.getPaddingBottom();
Like all coordinats (left right etc...)
After this you need the Height and Width of the ImageView.
Nah, when you know the views position, hegiht and width you can calculate.
Example:
final ImageView iv_YourImage = (ImageView) findViewById(R.id.iv_imageview);
public boolean onTouch(View v, MotionEvent event){
int topParam = iv_YourImage.getPaddingTop();
int rightParam = iv_YourImage.getPaddingRight();
int maxTopParam = topParam+iv_YourImage.getMaxHeight();
int maxRightParam = rightParam + iv_YourImage.getMaxWidth();
if(event.getX>topParam&&event.getX<maxTopParam){
//the x coordinate is in your image... do the same to Y
}
return true;
}
look at the following code if the answer is too short:
Android: Detect touch on actual image in ImageView
the code replaces the padding and max height coding of this answer and replaces it with the actual width and height of the displayed image using getWidth() and getHeight(). And uses the screen width and height to calculate its position. If you want more detailed answers for your problem you should give more information such as where did you draw the bitmap... did you define it at the activity XML or did you draw it at a random location such as at the X and Y coordinates of a touch event, the answer depends on that information.
package com.example.img;
imports....
public Image extends Activity {
ImageView imgYourImage;
// int imgWidth;
// etc...
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_image);
imgYourImage = (ImageView) findViewById(R.id.yourImage);
imgDimension();
}
private void imgDimension() {
imgWidth = imgYourImage.getWidth();
// at newer api's you can use getLeft() and getTop() of imageView
// if getLeft() works you have the leftX coordinate of image already.
// do same with height
// also get the screen Width and Height by display.getWidth() (depreciated)
// Or the newer code display.getSize()
leftX = (screenwidth - imgWidth) / 2;
rightx = leftx + imgWidth;
}
Notice that this code only works when the image is displayed at the horizontal center of the screen. Or use top and bottom if the image is displayed at the vertical center of the screen.
I've customized imageview but its just rotating its bitmap not the whole view. I don't want to use animation because I'm dragging imageview as well so moving animated imageivew results weird, so sticking to onDraw/draw, plus overriding draw is nothing doing special.
#Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
canvas.save();
canvas.rotate(rotationAngle, rotationW, rotationH);
super.onDraw(canvas);
canvas.restore();
}
how can I rotate the whole view not only its bitmap??
I did not get the provided answers intend here, but using
android:clipChildren="false"
for the parent ViewGroup
and overriding draw instead of onDraw did the job for me
For further information see:
Rotating imageview and its background without cropp
One must check width and height of the imageview, if Height > width then at the time of rotation width must be equal to height and same with height.
Make width and height equal to fill_parent and then rotate/translate/scale via matrix.
Starting with API 11, there is the following method available for each view:
.setRotation(float angle);
http://developer.android.com/reference/android/view/View.html#attr_android:rotation
Before API 11 you could add a rotate to the main-element of your view:
#Override
protected void onDraw(Canvas c) {
c.save();
c.rotate(...);
super.onDraw(c);
c.restore();
}