android: auto-scaling textView in dialog - android

I am trying to set the TextView to be auto scale inside the dialog,
xml
<com.abc.abc.AutoResizeTextView
android:id="#+id/text_btn"
android:layout_width="0dp"
android:layout_height="fill_parent"
android:layout_above="#+id/view2"
android:layout_alignLeft="#+id/linear_layout_color1"
android:layout_alignRight="#+id/linear_layout_color1"
android:layout_alignTop="#+id/doodleView"
android:layout_margin="1dp"
android:background="#color/white"
android:gravity="center"
android:text="A"
android:textColor="#color/grey" />
AutoResizeTextView
and AutoResizeTextView as in
Auto Scale TextView Text to Fit within Bounds
and then in java code
AutoResizeTextView textView = (AutoResizeTextView ) writing_dialog.findViewById(R.id.text_btn);
textView.setText("B");
Question:
I do not know why the text B is still appearing very small and not auto-scaling...
Thanks for your advice!

I am using this version of auto fit text view, which works great:
public class AutoFitTextView extends TextView {
public AutoFitTextView(Context context) {
super(context);
init();
}
public AutoFitTextView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
maxTextSize = this.getTextSize();
if (maxTextSize < 35) {
maxTextSize = 30;
}
minTextSize = 20;
}
private void refitText(String text, int textWidth) {
if (textWidth > 0) {
int availableWidth = textWidth - this.getPaddingLeft()
- this.getPaddingRight();
float trySize = maxTextSize;
this.setTextSize(TypedValue.COMPLEX_UNIT_PX, trySize);
while ((trySize > minTextSize)
&& (this.getPaint().measureText(text) > availableWidth)) {
trySize -= 1;
if (trySize <= minTextSize) {
trySize = minTextSize;
break;
}
this.setTextSize(TypedValue.COMPLEX_UNIT_PX, trySize);
}
this.setTextSize(TypedValue.COMPLEX_UNIT_PX, trySize);
}
}
#Override
protected void onTextChanged(final CharSequence text, final int start,
final int before, final int after) {
refitText(text.toString(), this.getWidth());
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
if (w != oldw) {
refitText(this.getText().toString(), w);
}
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int parentWidth = MeasureSpec.getSize(widthMeasureSpec);
refitText(this.getText().toString(), parentWidth);
}
public float getMinTextSize() {
return minTextSize;
}
public void setMinTextSize(int minTextSize) {
this.minTextSize = minTextSize;
}
public float getMaxTextSize() {
return maxTextSize;
}
public void setMaxTextSize(int minTextSize) {
this.maxTextSize = minTextSize;
}
private float minTextSize;
private float maxTextSize;
}
also set the width to:
android:layout_width="match_parent"

Related

Rectangle draw call in mainActivity

I draw a rectangle in the activity_main folder and I get these values to be drawn in integer.xml, but I do not want to do that.getInteger (R.integer.scanner_rect_width and getResources (). getInteger (R.integer.scanner_rect_height I get these values from the integer.xml folder, but how do I assign these values by creating a mainActivity object?
ScannerOverlay scannerOverlay = new ScannerOverlay (); as
ScanerOverlay.java
public class ScannerOverlay extends ViewGroup {
private float left, top, endY;
private int rectWidth, rectHeight;
private int frames;
private boolean revAnimation;
private int lineColor, lineWidth;
public ScannerOverlay(Context context) {
super(context);
}
public void setWidth(int pixels) {
rectWidth = pixels;
requestLayout();
invalidate();
}
public void setHeight(int pixels) {
rectHeight = pixels;
requestLayout();
invalidate();
}
public ScannerOverlay(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ScannerOverlay(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
TypedArray a = context.getTheme().obtainStyledAttributes(
attrs,
R.styleable.ScannerOverlay,
0, 0);
rectWidth = a.getInteger(R.styleable.ScannerOverlay_square_width, 150);
rectHeight = a.getInteger(R.styleable.ScannerOverlay_square_height, 150);
lineColor = a.getColor(R.styleable.ScannerOverlay_line_color, ContextCompat.getColor(context, R.color.scanner_line));
lineWidth = a.getInteger(R.styleable.ScannerOverlay_line_width, getResources().getInteger(R.integer.line_width));
frames = a.getInteger(R.styleable.ScannerOverlay_line_speed, getResources().getInteger(R.integer.line_width));
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);
}
#Override
public void onLayout(boolean changed, int left, int top, int right, int bottom) {
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
left = (w - dpToPx(rectWidth)) / 2;
top = (h - dpToPx(rectHeight)) / 2;
endY = top;
super.onSizeChanged(w, h, oldw, oldh);
}
public int dpToPx(int dp) {
DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
return Math.round(dp * (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT));
}
#Override
public boolean shouldDelayChildPressedState() {
return false;
}
#Override
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// draw transparent rect
int cornerRadius = 0;
Paint eraser = new Paint();
eraser.setAntiAlias(true);
eraser.setColor(Color.WHITE);
RectF rect = new RectF(left, top, dpToPx(rectWidth) + left, dpToPx(rectHeight) + top);
canvas.drawRoundRect(rect, (float) cornerRadius, (float) cornerRadius, eraser);
// draw horizontal line
Paint line = new Paint();
line.setColor(lineColor);
line.setStrokeWidth(Float.valueOf(lineWidth));
// draw the line to product animation
if (endY >= top + dpToPx(rectHeight) + frames) {
revAnimation = true;
} else if (endY == top + frames) {
revAnimation = false;
}
// check if the line has reached to bottom
if (revAnimation) {
endY -= frames;
} else {
endY += frames;
}
canvas.drawLine(left, endY, left + dpToPx(rectWidth), endY, line);
invalidate();
}
}
activity_main.xml
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.yavuz.myapplication.MainActivity">
<com.example.yavuz.myapplication.ScannerOverlay
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#44000000"
app:line_color="#7323DC"
app:line_speed="6"
app:line_width="4"
/>
MainActivity.java
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
You have to create setters methods for width and height as below:
public void setWidth(int pixels) {
rectWidth = pixels;
requestLayout();
invalidate();
}
public void setHeight(int pixels) {
rectHeight = pixels;
requestLayout();
invalidate();
}
Then to use it MainActivity you use it as below:
ScannerOverlay scannerOverlay = new ScannerOverlay();
scannerOverlay.setWidth(200); // for example
scannerOverlay.setHeight(300);
setContentView(scannerOverlay);
I suppose that ScannerOverlay is a custom view.
from xml layout:
<thepackage_where_theclass.ScannerOverlay
app:scanner_rect_width="200"
app:scanner_rect_height="200"/>

Round Custom Progress Bar with segments

I am trying to develop custom progress bar or view, where I can pass in section value and it will create a section in that and then I will fill as per my requirements.
I tired Progress bar with divider but it not in round one ..
Looking for some thing like this
Edit:-
i have edited code as per my need but it not able to do like given image
public class DashedCircularProgress extends RelativeLayout {
public DashedCircularProgress(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
public DashedCircularProgress(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context, attrs);
}
/**
* All the children must have a max height and width, never bigger than the internal circle
*
* #param changed
* #param left
* #param top
* #param right
* #param bottom
*/
#Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
final int count = getChildCount();
int maxWidth = getWidth() / 2;
int maxHeight = getHeight() / 2;
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
int mesaureWidth = child.getMeasuredWidth();
int measureHeight = child.getMeasuredWidth();
ViewGroup.LayoutParams layoutParams = child.getLayoutParams();
child.setTranslationY(padingTop);
RelativeLayout.LayoutParams relativeLayoutParams =
(RelativeLayout.LayoutParams) child.getLayoutParams();
relativeLayoutParams.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE);
child.setLayoutParams(relativeLayoutParams);
if (mesaureWidth > maxWidth) {
layoutParams.width = maxWidth;
}
if (measureHeight > maxHeight) {
layoutParams.height = maxHeight;
}
}
}
private void init(Context context, AttributeSet attributeSet) {
setWillNotDraw(false);
TypedArray attributes = context.obtainStyledAttributes(attributeSet,
R.styleable.DashedCircularProgress);
initAttributes(attributes);
initPainters();
initValueAnimator();
}
private void initAttributes(TypedArray attributes) {
externalColor = attributes.getColor(R.styleable.DashedCircularProgress_external_color,
externalColor);
internalBaseColor = attributes.getColor(R.styleable.DashedCircularProgress_base_color,
internalBaseColor);
progressColor = attributes.getColor(R.styleable.DashedCircularProgress_progress_color,
progressColor);
max = attributes.getFloat(R.styleable.DashedCircularProgress_max, max);
duration = attributes.getInt(R.styleable.DashedCircularProgress_duration, duration);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
progressPainter.onSizeChanged(h, w);
// externalCirclePainter.onSizeChanged(h, w);
internalCirclePainter.onSizeChanged(h, w);
//iconPainter.onSizeChanged(h, w);
animateValue();
}
private void initPainters() {
progressPainter = new ProgressPainterImp(progressColor, min, max);
//externalCirclePainter = new ExternalCirclePainterImp(externalColor);
internalCirclePainter = new InternalCirclePainterImp(internalBaseColor);
//iconPainter = new IconPainter(image);
}
private void initValueAnimator() {
valueAnimator = new ValueAnimator();
valueAnimator.setInterpolator(interpolator);
valueAnimator.addUpdateListener(new ValueAnimatorListenerImp());
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//externalCirclePainter.draw(canvas);
internalCirclePainter.draw(canvas);
progressPainter.draw(canvas);
//iconPainter.draw(canvas);
invalidate();
}
public void setValue(float value) {
this.value = value;
if (value <= max || value >= min) {
animateValue();
}
}
private void animateValue() {
if (valueAnimator != null) {
valueAnimator.setFloatValues(last, value);
valueAnimator.setDuration(duration);
valueAnimator.start();
}
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec + heightNormalittation);
}
public void setOnValueChangeListener(OnValueChangeListener valueChangeListener) {
this.valueChangeListener = valueChangeListener;
}
public void setInterpolator(Interpolator interpolator) {
this.interpolator = interpolator;
if (valueAnimator != null) {
valueAnimator.setInterpolator(interpolator);
}
}
public float getMin() {
return min;
}
public void setMin(float min) {
this.min = min;
progressPainter.setMin(min);
}
public float getMax() {
return max;
}
public void setMax(float max) {
this.max = max;
progressPainter.setMax(max);
}
private class ValueAnimatorListenerImp implements ValueAnimator.AnimatorUpdateListener {
#Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
Float value = (Float) valueAnimator.getAnimatedValue();
progressPainter.setValue(value);
if (valueChangeListener != null) {
valueChangeListener.onValueChange(value);
}
last = value;
}
}
public interface OnValueChangeListener {
void onValueChange(float value);
}
public void setIcon(int drawable) {
}
public void reset() {
last = min;
}
public int getProgressColor() {
return progressColor;
}
public void setProgressColor(int progressColor) {
this.progressColor = progressColor;
progressPainter.setColor(progressColor);
}
public int getInternalBaseColor() {
return internalBaseColor;
}
public void setInternalBaseColor(int internalBaseColor) {
this.internalBaseColor = internalBaseColor;
internalCirclePainter.setColor(progressColor);
}
public int getExternalColor() {
return externalColor;
}
public void setExternalColor(int externalColor) {
this.externalColor = externalColor;
// externalCirclePainter.setColor(externalColor);
}
public int getDuration() {
return duration;
}
public void setDuration(int duration) {
this.duration = duration;
}
}

AutoResizeTextView: different resize behavior on some old android version

I have this class that implement an AutoResizeTextView:
public class AutoResizeTv extends TextView {
private float minTextSize = 2;
private float maxTextSize = 25;
public AutoResizeTv(Context context) {
super(context);
init();
}
public AutoResizeTv(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
maxTextSize = this.getTextSize();
if (maxTextSize < 35) {
maxTextSize = 25;
}
minTextSize = 2;
}
private void refitText(String text, int textWidth) {
if (textWidth > 0) {
int availableWidth = textWidth - this.getPaddingLeft()
- this.getPaddingRight();
float trySize = maxTextSize;
this.setTextSize(TypedValue.COMPLEX_UNIT_PX, trySize);
while ((trySize > minTextSize)
&& (this.getPaint().measureText(text) > availableWidth)) {
trySize -= 1;
if (trySize <= minTextSize) {
trySize = minTextSize;
break;
}
this.setTextSize(TypedValue.COMPLEX_UNIT_PX, trySize);
}
this.setTextSize(TypedValue.COMPLEX_UNIT_PX, trySize);
}
}
#Override
protected void onTextChanged(final CharSequence text, final int start,
final int before, final int after) {
refitText(text.toString(), this.getWidth());
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
if (w != oldw) {
refitText(this.getText().toString(), w);
}
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int parentWidth = MeasureSpec.getSize(widthMeasureSpec);
refitText(this.getText().toString(), parentWidth);
}
public float getMinTextSize() {
return minTextSize;
}
public void setMinTextSize(int minTextSize) {
this.minTextSize = minTextSize;
}
public float getMaxTextSize() {
return maxTextSize;
}
public void setMaxTextSize(int minTextSize) {
this.maxTextSize = minTextSize;
}
On most Android devices it works well, but i've noticed that on some old Android version (for example a tablet with sdk version 13) , text is not scaled to fit its container.
How can i fix it for get the same behavior on all android devices (i prefer to edit this class instead use a new AutoResizeTextView implementation)

Canvas not clear on android 4.2.2

I have a customview , inside it , i have one view slide up and down , when slide i draw fade background like this :
#Override
protected void dispatchDraw(Canvas canvas) {
canvas.drawARGB(alpha, 0, 0, 0);
super.dispatchDraw(canvas);
}
It work with my device android 4.2.2 but with android 4.4.2 or google nexus one android 2.3.7 ,it so bad.
2 images below show in my device 4.2.2(slide in and slide out):
http://imgur.com/p6i9gw8
http://imgur.com/9Sdzy7v
and 2 images below show in google nexus one android 2.3.7(slide in and slide out):
http://imgur.com/ZGKiRJi
http://imgur.com/Uf3vRdb
As you can see, in 2 image first, fade draw correct , and in other, it look bad.
Complete code for this view is :
public class SlideView extends ViewGroup {
private static final int MAXDURATIONSLIDE = 500;
protected View content;
private int childHeight;
private int childOffset;
private int childWidth;
private int alpha;
private Fillinger fillinger;
public ISlide getSlideChangeListener() {
return slideListener;
}
public void setSlideChangeListener(ISlide slideChangeListener) {
this.slideListener = slideChangeListener;
}
private ISlide slideListener;
public SlideView(Context context) {
super(context);
init(context, null);
}
private void init(Context context, AttributeSet attrs) {
if(attrs!=null){
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SlideView);
try {
int contentLayoutId = a.getResourceId(R.styleable.SlideView_slideView, 0);
DebugLog.d(contentLayoutId);
setContent(contentLayoutId);
} finally {
a.recycle();
}
}
fillinger = new Fillinger(context);
}
public SlideView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context,attrs);
}
#Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
final int width = r - l;
final int height = b - t;
DebugLog.d("width "+width+" height "+height);
childOffset = height;
content.layout(0, childOffset, childWidth, childOffset + childHeight);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = getDefaultSize(0, widthMeasureSpec);
int height = getDefaultSize(0, heightMeasureSpec);
measureChild(content, widthMeasureSpec, height);
childHeight = content.getMeasuredHeight();
childWidth = content.getMeasuredWidth();
DebugLog.d("childWidth "+childWidth+" childHeight "+childHeight);
setMeasuredDimension(width, height);
}
public void setContent(int resId) {
View view = LayoutInflater.from(getContext()).inflate(resId, this,false);
setContent(view);
}
public void setContent(View v) {
if (content != null)
removeView(content);
content = v;
addView(content);
}
private void moveViewByY(int diffY) {
childOffset += diffY;
alpha = (int) (Math.abs((getHeight()-childOffset)*255/(childHeight))*0.5f);
content.layout(0, childOffset, childWidth, childOffset + childHeight);
if(slideListener!=null){
slideListener.onSlide(childOffset,childHeight);
}
}
#Override
protected void dispatchDraw(Canvas canvas) {
canvas.drawARGB(alpha, 0, 0, 0);
super.dispatchDraw(canvas);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
if(isIn()&&touchOutSide(event)){
toogle();
return true;
}
return false;
}
private boolean touchOutSide(MotionEvent event) {
final float x = event.getX();
final float y = event.getY();
if(x<content.getLeft()||x>content.getRight()||y<content.getTop()||y>content.getBottom()){
return true;
}
return false;
}
public void hide(){
if(isIn()){
fillinger.startScroll(content.getTop(),getHeight(),childHeight,MAXDURATIONSLIDE);
}
}
public void show(){
if(!isIn()){
fillinger.startScroll(content.getTop(),getHeight()-childHeight,childHeight,MAXDURATIONSLIDE);
}
}
public void toogle(){
fillinger.cancleAnimation();
if(isIn()){
hide();
}else{
show();
}
}
public boolean isIn(){
return content.getTop()<getHeight();
}
public class Fillinger implements Runnable {
private static final String tag = "Fillinger";
private Scroller mScroller;
private int lastY;
private boolean more;
private int currentY;
private int diffY;
public Fillinger(Context context) {
mScroller = new Scroller(context);
}
public void startScroll(float startY, float endY, float maxDistance, int maxDurationForFling) {
int duration = (int) Math.min(Math.abs((endY - startY)) / maxDistance * maxDurationForFling, maxDurationForFling);
lastY = (int) startY;
if(slideListener!=null){
slideListener.onStartSlide();
}
mScroller.startScroll(0, (int) startY, 0, -(int) (endY - startY), duration);
setDrawingCacheEnabled(true);
post(this);
}
public void cancleAnimation(){
removeCallbacks(this);
}
#Override
public void run() {
more = mScroller.computeScrollOffset();
currentY = mScroller.getCurrY();
diffY = lastY - currentY;
moveViewByY(diffY);
lastY = currentY;
if (more) {
post(this);
}else{
setDrawingCacheEnabled(false);
if(slideListener!=null){
slideListener.onSlideFinish(isIn());
}
}
}
}
}
What i missing?
Sorry for my bad english.
Thanks all.
Edit: finally , i must call invalidate in moveViewByY method like this
private void moveViewByY(int diffY) {
childOffset += diffY;
alpha = (int) (Math.abs((getHeight()-childOffset)*255/(childHeight))*0.5f);
content.layout(0, childOffset, childWidth, childOffset + childHeight);
invalidate();
if(slideListener!=null){
slideListener.onSlide(childOffset,childHeight);
}
}
I dont know why , may be invalidate , view tree redraw and old canvas cleared.
Expect best solution, thanks .

Surfaceview xml layout

I have a surfaceview that displays a background image and a crosshair that appears on the coordinates where the user touches the screen.
I have two problems.
1) The screen is black until I touch the screen, and at that moment both images are drawn on the screen and it works fine. Why is the screen black until I touch it?
2) How can I use my own xml layout?
I have tried using setContentView(R.layout.image_edit_activity);
and having a framelayout like this:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<com.effbe.accelerometer.ImageEditActivity.Crosshair
android:id="#+id/surfaceView"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<Button
android:id="#+id/button1"
android:layout_width="114dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="#drawable/ok_button"
android:padding="10dp"
android:paddingLeft="10dip"
android:text="OK"
android:textColor="#ffffff" />
</LinearLayout>
</FrameLayout>
But I have not been able to solve this problem.
public class ImageEditActivity extends Activity {
public String reportDate;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = getIntent();
reportDate = intent.getStringExtra("reportDate");
int w = getWindowManager().getDefaultDisplay().getWidth() - 25;
int h = getWindowManager().getDefaultDisplay().getHeight() - 25;
Crosshair crosshairView = new Crosshair(this, w, h, reportDate);
setContentView(crosshairView);
}
}
class Crosshair extends SurfaceView implements SurfaceHolder.Callback {
private Bitmap bitmap;
private int x = 20, y = 20;
int width, height;
String reportDate1;
public Crosshair(Context context, int w, int h, String reportDate) {
super(context);
reportDate1 = reportDate;
width = w;
height = h;
getHolder().addCallback(this);
setFocusable(true);
}
public Crosshair(Context context) {
super(context);
}
public Crosshair(Context context, int w, int h) {
super(context);
}
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
String path = Environment.getExternalStorageDirectory()
.getAbsolutePath()
+ "/VibrationMeasurement/"
+ reportDate1
+ ".machine" + ".jpg";
Bitmap bitmap2 = BitmapFactory.decodeFile(path);
Bitmap scaled = Bitmap.createScaledBitmap(bitmap2, width, height, true);
bitmap = BitmapFactory.decodeResource(getResources(),
R.drawable.crosshair);
// canvas.drawColor(Color.BLUE);//To make background
canvas.drawBitmap(scaled, 0, 0, null);
canvas.drawBitmap(bitmap, x - (bitmap.getWidth() / 2),
y - (bitmap.getHeight() / 2), null);
// canvas.drawBitmap(;
}
#Override
public boolean onTouchEvent(MotionEvent event) {
x = (int) event.getX();
y = (int) event.getY();
if (x < 25)
x = 25;
if (x > width)
x = width;
if (y < 25)
y = 25;
if (y > height)
y = height;
updateCrosshair();
return true;
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
}
private void updateCrosshair() {
Canvas canvas = null;
try {
canvas = getHolder().lockCanvas(null);
synchronized (getHolder()) {
this.onDraw(canvas);
}
} finally {
if (canvas != null) {
getHolder().unlockCanvasAndPost(canvas);
}
}
}
}
This should sort you out.
activity_image_edit.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<view
class="com.effbe.accelerometer.ImageEditActivity$CrosshairView"
android:id="#+id/crosshairView"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<Button
android:id="#+id/button1"
android:layout_width="114dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:padding="10dp"
android:paddingLeft="10dip"
android:background="#drawable/ok_button"
android:text="OK"
android:textColor="#ffffff"
/>
</LinearLayout>
</FrameLayout>
ImageEditActivity.java
package com.effbe.accelerometer;
import android.content.Context;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.ImageView;
import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.widget.Toast;
public class ImageEditActivity extends Activity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
String reportDate = getIntent().getStringExtra("reportDate");
String reportPath = Environment.getExternalStorageDirectory().getAbsolutePath() +
"/VibrationMeasurement/" + reportDate + ".machine" + ".jpg";
setContentView(R.layout.activity_image_edit);
CrosshairView crosshairView = (CrosshairView)findViewById(R.id.crosshairView);
crosshairView.setImagePath(reportPath);
crosshairView.setOnCrosshairChanged(new CrosshairView.OnCrosshairChanged()
{
#Override
public void onCrosshairChanged(CrosshairView view, int x, int y, int w, int h)
{
Toast.makeText(view.getContext(), "Pos: " + x + ", " + y, Toast.LENGTH_SHORT).show();
}
});
}
public static class CrosshairView extends ImageView
{
private static final String TAG = CrosshairView.class.getSimpleName();
private Drawable mCrosshairDrawable;
private int mCrosshairX = -1;
private int mCrosshairY = -1;
private OnCrosshairChanged mListener;
private String mImagePath;
public CrosshairView(Context context)
{
super(context);
initView(context, null);
}
public CrosshairView(Context context, AttributeSet attrs)
{
super(context, attrs);
initView(context, attrs);
}
public CrosshairView(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs, defStyle);
initView(context, attrs);
}
protected void initView(Context context, AttributeSet attrs)
{
mCrosshairDrawable = getResources().getDrawable(R.drawable.crosshair);
}
public void setOnCrosshairChanged(OnCrosshairChanged listener)
{
mListener = listener;
}
public void setImagePath(String imagePath)
{
mImagePath = imagePath;
updateImage();
}
public String getImagePath()
{
return mImagePath;
}
public int getCrosshairX()
{
return mCrosshairX;
}
public int getCrosshairY()
{
return mCrosshairY;
}
private void updateImage()
{
int width = getWidth();
int height = getHeight();
if(width == 0 || height == 0){
return;
}
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(mImagePath, options);
options.inSampleSize = calculateInSampleSize(options, width, height);
options.inJustDecodeBounds = false;
setImageBitmap(BitmapFactory.decodeFile(mImagePath, options));
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh)
{
super.onSizeChanged(w, h, oldw, oldh);
if(mCrosshairX < 0 || mCrosshairY < 0){
mCrosshairX = w / 2;
mCrosshairY = h / 2;
}
updateImage();
}
#Override
public boolean onTouchEvent(MotionEvent event)
{
final int action = event.getAction();
if(action != MotionEvent.ACTION_CANCEL){
mCrosshairX = (int)event.getX();
mCrosshairY = (int)event.getY();
if(action == MotionEvent.ACTION_UP){
if(mListener != null){
mListener.onCrosshairChanged(this, mCrosshairX, mCrosshairY, getWidth(), getHeight());
}
}
postInvalidate();
}
return true;
}
#Override
protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
final int w2 = mCrosshairDrawable.getIntrinsicWidth() / 2;
final int h2 = mCrosshairDrawable.getIntrinsicHeight() / 2;
mCrosshairDrawable.setBounds(mCrosshairX - w2, mCrosshairY - h2, mCrosshairX + w2, mCrosshairY + h2);
mCrosshairDrawable.draw(canvas);
}
private static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight)
{
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if(height > reqHeight || width > reqWidth){
final int halfHeight = height / 2;
final int halfWidth = width / 2;
while((halfHeight / inSampleSize) > reqHeight && (halfWidth / inSampleSize) > reqWidth){
inSampleSize *= 2;
}
}
return inSampleSize;
}
public static interface OnCrosshairChanged
{
public void onCrosshairChanged(CrosshairView view, int x, int y, int w, int h);
}
}
}
Maybe this?
#Override
public void surfaceCreated(SurfaceHolder holder) {
updateCrosshair();
}

Categories

Resources