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();
}
Related
I created a cornerRadius card view and my codes work well in activity but the problem now is that the cardview does not show the rounded edges and elevation in fragment but it shows in the design codes and in activity. my codes are shown blow:
raounded_corners.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:focusable="true"
android:clickable="true"
android:background="#color/white"
android:layout_height="match_parent">
<com.google.android.material.card.MaterialCardView
android:id="#+id/text_bg"
android:layout_width="110dp"
android:layout_height="110dp"
app:cardBackgroundColor="#color/green_500"
app:cardCornerRadius="50dp"
app:cardElevation="5dp"
android:layout_gravity="center"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:id="#+id/image_session"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#android:color/transparent"
android:src="#drawable/photo_male_7" />
</com.google.android.material.card.MaterialCardView>
</RelativeLayout>
In Fragment
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.raounded_corners,container,false);
return v;
}
raounded_corners.xml layout cornerRadius showing in activity but not showing in fragment
How to fix this.
In Activity
in fragment
If you are trying to make the imageview circular, I propose this approach.Create the custom view and set it in your xml. It works perfectly. If this helps you, an upvote will be appreciated.
Create a custom Circular view like shown below. CircleImageView.java
package com.fishpott.fishpott5.Views;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.support.annotation.ColorInt;
import android.support.annotation.ColorRes;
import android.support.annotation.DrawableRes;
import android.support.v7.widget.AppCompatImageView;
import android.util.AttributeSet;
import android.widget.ImageView;
import com.fishpott.fishpott5.R;
public class CircleImageView extends AppCompatImageView {
private static final ImageView.ScaleType SCALE_TYPE = ImageView.ScaleType.CENTER_CROP;
private static final Bitmap.Config BITMAP_CONFIG = Bitmap.Config.ARGB_8888;
private static final int COLORDRAWABLE_DIMENSION = 2;
private static final int DEFAULT_BORDER_WIDTH = 0;
private static final int DEFAULT_BORDER_COLOR = Color.BLACK;
private static final int DEFAULT_FILL_COLOR = Color.TRANSPARENT;
private static final boolean DEFAULT_BORDER_OVERLAY = false;
private final RectF mDrawableRect = new RectF();
private final RectF mBorderRect = new RectF();
private final Matrix mShaderMatrix = new Matrix();
private final Paint mBitmapPaint = new Paint();
private final Paint mBorderPaint = new Paint();
private final Paint mFillPaint = new Paint();
private int mBorderColor = DEFAULT_BORDER_COLOR;
private int mBorderWidth = DEFAULT_BORDER_WIDTH;
private int mFillColor = DEFAULT_FILL_COLOR;
private Bitmap mBitmap;
private BitmapShader mBitmapShader;
private int mBitmapWidth;
private int mBitmapHeight;
private float mDrawableRadius;
private float mBorderRadius;
private ColorFilter mColorFilter;
private boolean mReady;
private boolean mSetupPending;
private boolean mBorderOverlay;
private boolean mDisableCircularTransformation;
public CircleImageView(Context context) {
super(context);
init();
}
public CircleImageView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CircleImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CircleImageView, defStyle, 0);
mBorderWidth = a.getDimensionPixelSize(R.styleable.CircleImageView_civ_border_width, DEFAULT_BORDER_WIDTH);
mBorderColor = a.getColor(R.styleable.CircleImageView_civ_border_color, DEFAULT_BORDER_COLOR);
mBorderOverlay = a.getBoolean(R.styleable.CircleImageView_civ_border_overlay, DEFAULT_BORDER_OVERLAY);
mFillColor = a.getColor(R.styleable.CircleImageView_civ_fill_color, DEFAULT_FILL_COLOR);
a.recycle();
init();
}
private void init() {
super.setScaleType(SCALE_TYPE);
mReady = true;
if (mSetupPending) {
setup();
mSetupPending = false;
}
}
#Override
public ImageView.ScaleType getScaleType() {
return SCALE_TYPE;
}
#Override
public void setScaleType(ImageView.ScaleType scaleType) {
if (scaleType != SCALE_TYPE) {
throw new IllegalArgumentException(String.format("ScaleType %s not supported.", scaleType));
}
}
#Override
public void setAdjustViewBounds(boolean adjustViewBounds) {
if (adjustViewBounds) {
throw new IllegalArgumentException("adjustViewBounds not supported.");
}
}
#Override
protected void onDraw(Canvas canvas) {
if (mDisableCircularTransformation) {
super.onDraw(canvas);
return;
}
if (mBitmap == null) {
return;
}
if (mFillColor != Color.TRANSPARENT) {
canvas.drawCircle(mDrawableRect.centerX(), mDrawableRect.centerY(), mDrawableRadius, mFillPaint);
}
canvas.drawCircle(mDrawableRect.centerX(), mDrawableRect.centerY(), mDrawableRadius, mBitmapPaint);
if (mBorderWidth > 0) {
canvas.drawCircle(mBorderRect.centerX(), mBorderRect.centerY(), mBorderRadius, mBorderPaint);
}
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
setup();
}
#Override
public void setPadding(int left, int top, int right, int bottom) {
super.setPadding(left, top, right, bottom);
setup();
}
#Override
public void setPaddingRelative(int start, int top, int end, int bottom) {
super.setPaddingRelative(start, top, end, bottom);
setup();
}
public int getBorderColor() {
return mBorderColor;
}
public void setBorderColor(#ColorInt int borderColor) {
if (borderColor == mBorderColor) {
return;
}
mBorderColor = borderColor;
mBorderPaint.setColor(mBorderColor);
invalidate();
}
/**
* #deprecated Use {#link #setBorderColor(int)} instead
*/
#Deprecated
public void setBorderColorResource(#ColorRes int borderColorRes) {
setBorderColor(getContext().getResources().getColor(borderColorRes));
}
/**
* Return the color drawn behind the circle-shaped drawable.
*
* #return The color drawn behind the drawable
*
* #deprecated Fill color support is going to be removed in the future
*/
#Deprecated
public int getFillColor() {
return mFillColor;
}
/**
* Set a color to be drawn behind the circle-shaped drawable. Note that
* this has no effect if the drawable is opaque or no drawable is set.
*
* #param fillColor The color to be drawn behind the drawable
*
* #deprecated Fill color support is going to be removed in the future
*/
#Deprecated
public void setFillColor(#ColorInt int fillColor) {
if (fillColor == mFillColor) {
return;
}
mFillColor = fillColor;
mFillPaint.setColor(fillColor);
invalidate();
}
/**
* Set a color to be drawn behind the circle-shaped drawable. Note that
* this has no effect if the drawable is opaque or no drawable is set.
*
* #param fillColorRes The color resource to be resolved to a color and
* drawn behind the drawable
*
* #deprecated Fill color support is going to be removed in the future
*/
#Deprecated
public void setFillColorResource(#ColorRes int fillColorRes) {
setFillColor(getContext().getResources().getColor(fillColorRes));
}
public int getBorderWidth() {
return mBorderWidth;
}
public void setBorderWidth(int borderWidth) {
if (borderWidth == mBorderWidth) {
return;
}
mBorderWidth = borderWidth;
setup();
}
public boolean isBorderOverlay() {
return mBorderOverlay;
}
public void setBorderOverlay(boolean borderOverlay) {
if (borderOverlay == mBorderOverlay) {
return;
}
mBorderOverlay = borderOverlay;
setup();
}
public boolean isDisableCircularTransformation() {
return mDisableCircularTransformation;
}
public void setDisableCircularTransformation(boolean disableCircularTransformation) {
if (mDisableCircularTransformation == disableCircularTransformation) {
return;
}
mDisableCircularTransformation = disableCircularTransformation;
initializeBitmap();
}
#Override
public void setImageBitmap(Bitmap bm) {
super.setImageBitmap(bm);
initializeBitmap();
}
#Override
public void setImageDrawable(Drawable drawable) {
super.setImageDrawable(drawable);
initializeBitmap();
}
#Override
public void setImageResource(#DrawableRes int resId) {
super.setImageResource(resId);
initializeBitmap();
}
#Override
public void setImageURI(Uri uri) {
super.setImageURI(uri);
initializeBitmap();
}
#Override
public void setColorFilter(ColorFilter cf) {
if (cf == mColorFilter) {
return;
}
mColorFilter = cf;
applyColorFilter();
invalidate();
}
#Override
public ColorFilter getColorFilter() {
return mColorFilter;
}
private void applyColorFilter() {
if (mBitmapPaint != null) {
mBitmapPaint.setColorFilter(mColorFilter);
}
}
private Bitmap getBitmapFromDrawable(Drawable drawable) {
if (drawable == null) {
return null;
}
if (drawable instanceof BitmapDrawable) {
return ((BitmapDrawable) drawable).getBitmap();
}
try {
Bitmap bitmap;
if (drawable instanceof ColorDrawable) {
bitmap = Bitmap.createBitmap(COLORDRAWABLE_DIMENSION, COLORDRAWABLE_DIMENSION, BITMAP_CONFIG);
} else {
bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), BITMAP_CONFIG);
}
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
private void initializeBitmap() {
if (mDisableCircularTransformation) {
mBitmap = null;
} else {
mBitmap = getBitmapFromDrawable(getDrawable());
}
setup();
}
private void setup() {
if (!mReady) {
mSetupPending = true;
return;
}
if (getWidth() == 0 && getHeight() == 0) {
return;
}
if (mBitmap == null) {
invalidate();
return;
}
mBitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
mBitmapPaint.setAntiAlias(true);
mBitmapPaint.setShader(mBitmapShader);
mBorderPaint.setStyle(Paint.Style.STROKE);
mBorderPaint.setAntiAlias(true);
mBorderPaint.setColor(mBorderColor);
mBorderPaint.setStrokeWidth(mBorderWidth);
mFillPaint.setStyle(Paint.Style.FILL);
mFillPaint.setAntiAlias(true);
mFillPaint.setColor(mFillColor);
mBitmapHeight = mBitmap.getHeight();
mBitmapWidth = mBitmap.getWidth();
mBorderRect.set(calculateBounds());
mBorderRadius = Math.min((mBorderRect.height() - mBorderWidth) / 2.0f, (mBorderRect.width() - mBorderWidth) / 2.0f);
mDrawableRect.set(mBorderRect);
if (!mBorderOverlay && mBorderWidth > 0) {
mDrawableRect.inset(mBorderWidth - 1.0f, mBorderWidth - 1.0f);
}
mDrawableRadius = Math.min(mDrawableRect.height() / 2.0f, mDrawableRect.width() / 2.0f);
applyColorFilter();
updateShaderMatrix();
invalidate();
}
private RectF calculateBounds() {
int availableWidth = getWidth() - getPaddingLeft() - getPaddingRight();
int availableHeight = getHeight() - getPaddingTop() - getPaddingBottom();
int sideLength = Math.min(availableWidth, availableHeight);
float left = getPaddingLeft() + (availableWidth - sideLength) / 2f;
float top = getPaddingTop() + (availableHeight - sideLength) / 2f;
return new RectF(left, top, left + sideLength, top + sideLength);
}
private void updateShaderMatrix() {
float scale;
float dx = 0;
float dy = 0;
mShaderMatrix.set(null);
if (mBitmapWidth * mDrawableRect.height() > mDrawableRect.width() * mBitmapHeight) {
scale = mDrawableRect.height() / (float) mBitmapHeight;
dx = (mDrawableRect.width() - mBitmapWidth * scale) * 0.5f;
} else {
scale = mDrawableRect.width() / (float) mBitmapWidth;
dy = (mDrawableRect.height() - mBitmapHeight * scale) * 0.5f;
}
mShaderMatrix.setScale(scale, scale);
mShaderMatrix.postTranslate((int) (dx + 0.5f) + mDrawableRect.left, (int) (dy + 0.5f) + mDrawableRect.top);
mBitmapShader.setLocalMatrix(mShaderMatrix);
}
}
Set the view in your xml
<com.fishpott.fishpott5.Views.CircleImageView
android:id="#+id/activity_setprofilepicture_profilepicture_imageview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:contentDescription="#string/none"
android:src="#drawable/setprofilepicture_activity_imageholder_default_image"
app:civ_border_color="#android:color/transparent"
app:civ_border_width="0dp" />
The reason you see "Views" in my xml call of the CircleImageView is because my CircleImageView.java is in "Views" folder/package.
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"/>
I have tried to implement the youtube like draggable panel using the Customlayout which extends ViewGroup. I have made use of the onTouchEvents to create and scaling on dragging effect.
Now, the problem is that the when dragged down, the selected item resides near the bottom of the screen as it happens in YouTube. When clicked on that item in that position, it should get back to the full screen mode. But to do so, I implemented the onClicklistener for the view but it simply doesn't respond.
Also, when at the bottom, how do I restrict it's motion in the vertical direction and allow it to move in the horizontal direction as it happens in YouTube.
Here is the CustomLayout class called DraggablePanel.
package visio.com.eventpage;
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.support.v4.view.MotionEventCompat;
import android.support.v4.view.ViewCompat;
import android.support.v4.widget.ViewDragHelper;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import android.widget.Toast;
import static android.view.MotionEvent.INVALID_POINTER_ID;
/**
* Created by Rambo on 1/9/2018.
*/
public class DraggablePanel extends ViewGroup {
public final ViewDragHelper mDragHelper;
public View mHeaderView;
private View mDescView;
private float mInitialMotionX;
private float mInitialMotionY;
private int mDragRange;
private int mTop;
private float mDragOffset;
private Context context;
public int toponViewReleased;
public int screenWidth, screenHeight;
private String TAG = "DraggablePanel";
public void manualInvalidate(){
invalidate();
}
public DraggablePanel(Context context) {
this(context, null);
}
public DraggablePanel(Context context, AttributeSet attrs) {
this(context, attrs, 0);
this.context = context;
}
#Override
protected void onFinishInflate() {
super.onFinishInflate();
mHeaderView = findViewById(R.id.viewHeader);
mDescView = findViewById(R.id.viewDesc);
DisplayMetrics displayMetrics = new DisplayMetrics();
((Activity)context).getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
screenHeight = displayMetrics.heightPixels;
screenWidth = displayMetrics.widthPixels;
}
public DraggablePanel(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mDragHelper = ViewDragHelper.create(this, 1f, new DragHelperCallback());
}
private class DragHelperCallback extends ViewDragHelper.Callback {
#Override
public boolean tryCaptureView(View child, int pointerId) {
return child == mHeaderView;
}
#Override
public void onViewPositionChanged(View changedView, int left, int top, int dx, int dy) {
mTop = top;
float paddingOffset = (float)top/10;
mDragOffset = (float) top / mDragRange;
mHeaderView.setPivotX(mHeaderView.getWidth());
mHeaderView.setPivotY(mHeaderView.getHeight());
mHeaderView.setScaleX(1 - mDragOffset / 2);
mHeaderView.setScaleY(1 - mDragOffset / 2);
mHeaderView.setPadding(0,0,(int) paddingOffset, (int) paddingOffset);
mDescView.setAlpha(1 - mDragOffset);
if( top == 0){
}
requestLayout();
Log.d("onViewPositionChanged","Called");
}
#Override
public void onViewReleased(View releasedChild, float xvel, float yvel) {
int top = releasedChild.getTop()>screenHeight/3?screenHeight-150 - mHeaderView.getHeight():0;
Log.d("Heights","H1"+getHeight() + "child height" + releasedChild.getMeasuredHeight()+"top" +top);
mDragHelper.smoothSlideViewTo(releasedChild, releasedChild.getLeft(),top);
if( top!=0 ){
mDescView.setAlpha(0);
}
ViewCompat.postInvalidateOnAnimation(releasedChild);
toponViewReleased = top;
invalidate();
}
#Override
public int getViewVerticalDragRange(View child) {
return mDragRange;
}
#Override
public int clampViewPositionVertical(View child, int top, int dy) {
float descViewAlpha = mDescView.getAlpha();
final int topBound = getPaddingTop();
final int bottomBound = getHeight() - mHeaderView.getHeight() - 20;
int newTop = Math.min(Math.max(top, topBound), bottomBound);
if( descViewAlpha == 0 ){
newTop = 0;
}
Log.d(TAG,"clampVertical" + newTop);
return newTop;
}
#Override
public int clampViewPositionHorizontal(View child, int left, int dx) {
final int rightBound = mHeaderView.getPaddingRight();
final int leftBound = screenWidth - mHeaderView.getWidth() - 20;
int newTop = Math.min(Math.max(left, rightBound), leftBound);
if(mDescView.getAlpha() != 0){
newTop = 0;
}
Log.d(TAG,"clampHorizontal" + newTop);
return newTop;
}
}
#Override
public void computeScroll() {
if (mDragHelper.continueSettling(true)) {
ViewCompat.postInvalidateOnAnimation(this);
}
}
#Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
final int action = ev.getActionMasked();
if (( action != MotionEvent.ACTION_DOWN)) {
mDragHelper.cancel();
return super.onInterceptTouchEvent(ev);
}
final float x = ev.getX();
final float y = ev.getY();
boolean interceptTap = false;
switch (action) {
case MotionEvent.ACTION_DOWN: {
mInitialMotionX = x;
mInitialMotionY = y;
interceptTap = mDragHelper.isViewUnder(mHeaderView, (int) x, (int) y);
break;
}
case MotionEvent.ACTION_MOVE: {
final float adx = Math.abs(x - mInitialMotionX);
final float ady = Math.abs(y - mInitialMotionY);
final int slop = mDragHelper.getTouchSlop();
if (ady > slop && adx > ady) {
mDragHelper.cancel();
return false;
}
}
}
return mDragHelper.shouldInterceptTouchEvent(ev) || interceptTap;
}
#Override
public boolean onTouchEvent(MotionEvent ev) {
mDragHelper.processTouchEvent(ev);
final int action = ev.getAction();
final float x = ev.getX();
final float y = ev.getY();
boolean isHeaderViewUnder = mDragHelper.isViewUnder(mHeaderView, (int) x, (int) y);
switch (action & ev.getActionMasked()) {
case MotionEvent.ACTION_DOWN: {
mInitialMotionX = x;
mInitialMotionY = y;
break;
}
}
return isHeaderViewUnder && isViewHit(mHeaderView, (int) x, (int) y) || isViewHit(mDescView, (int) x, (int) y);
}
#Override
public boolean performClick() {
super.performClick();
if(toponViewReleased !=0){
mDragHelper.smoothSlideViewTo(mHeaderView, 0,0);
invalidate();
Log.d("DraggablePanel","Clicked top != 0");
}else{
Log.d("DraggablePanel","Clicked top == 0");
}
return true;
}
private boolean isViewHit(View view, int x, int y) {
int[] viewLocation = new int[2];
view.getLocationOnScreen(viewLocation);
int[] parentLocation = new int[2];
this.getLocationOnScreen(parentLocation);
int screenX = parentLocation[0] + x;
int screenY = parentLocation[1] + y;
return screenX >= viewLocation[0] && screenX < viewLocation[0] + view.getWidth() &&
screenY >= viewLocation[1] && screenY < viewLocation[1] + view.getHeight();
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
measureChildren(widthMeasureSpec, heightMeasureSpec);
int maxWidth = MeasureSpec.getSize(widthMeasureSpec);
int maxHeight = MeasureSpec.getSize(heightMeasureSpec);
setMeasuredDimension(resolveSizeAndState(maxWidth, widthMeasureSpec, 0),
resolveSizeAndState(maxHeight, heightMeasureSpec, 0));
}
#Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
Log.d(TAG,"onLayout Called");
mDragRange = getHeight() - mHeaderView.getHeight();
mHeaderView.layout(
0,
mTop,
r,
mTop + mHeaderView.getMeasuredHeight());
mDescView.layout(
0,
mTop + mHeaderView.getMeasuredHeight(),
r,
mTop + b);
}
}
Here is the Layout where the above class has been used.
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerViewEvents"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<visio.com.eventpage.DraggablePanel
android:id="#+id/draggablePanel"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:visibility="gone">
<ImageView
android:id="#+id/viewHeader"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_marginEnd="20dp"
android:gravity="center"
android:scaleType="fitXY"
android:src="#drawable/ic_event" />
<TextView
android:id="#+id/viewDesc"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FF00FF"
android:gravity="center"
android:tag="desc"
android:text="Loreum Loreum"
android:textColor="#android:color/white"
android:textSize="35sp" />
</visio.com.eventpage.DraggablePanel>
</FrameLayout>
i have got some problem with my own progressbar.
When i click on dot they catch me.
I try do it something like that:
here is code:
package test.pionas.myapplication;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.TypedArray;
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.RectF;
import android.os.Build;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
public class PioArcCircle extends View {
private static final String TAG = PioArc.class.getSimpleName();
private static int INVALID_PROGRESS_VALUE = -1;
private float mThickness = 50f; // thickness of line
private int mRotate = 0; // rotate circle in degrees
private Paint mCircleBgPaint;
private int mCircleEndAngle = 270; // end arc
private int mCircleStartAngle = 0; // start arc
private int mCircleSweepAngle = 0; // actualy arc
private RectF mCircleOuterBounds;
private int mCircleBgColor = Color.RED; // color of circle
private Paint mCirclePaint; // progressbar
private int mCircleColor = Color.BLUE; // color of progressbar
private Paint mEraserPaint;
private RectF mCircleInnerBounds;
private int mEraserColor = Color.YELLOW; // background color of circle
private boolean mEraserInnerBackground = false; // eraser background inner circle
private Bitmap mBitmap;
private Canvas mCanvas;
private float mMinValue = 0; // min progressbar value
private float mMaxValue = 100; // max progressbar value
private float mProgressSweep = 0; // start progressbar value
private boolean mEnabled; // draw dot
private float mDotSize; // dot size
private Paint mCircleThumbPaint;
private float mTranslateX; // center circle (axis X)
private float mTranslateY; // center circle (axis Y)
private boolean mTouchInside; // touch inside circle can change position on progress
private float mTouchIgnoreRadius;
private int mArcRadius;
private int mThumbXPos;
private int mThumbYPos;
private OnPioArcCircleChangeListener mOnPioArcCircleChangeListener;
public PioArcCircle(Context context) {
super(context);
initDefaultValue(context, 0, null);
}
public PioArcCircle(Context context, AttributeSet attrs) {
super(context, attrs);
initDefaultValue(context, 0, attrs);
}
public PioArcCircle(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initDefaultValue(context, defStyleAttr, attrs);
}
#TargetApi(Build.VERSION_CODES.LOLLIPOP)
public PioArcCircle(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
initDefaultValue(context, defStyleAttr, attrs);
}
private void initDefaultValue(Context context, int defStyleAttr, AttributeSet attrs) {
if (attrs != null) {
TypedArray typedArray = context.getTheme().obtainStyledAttributes(
attrs,
R.styleable.PioArcCircle,
defStyleAttr, 0);
this.mThickness = typedArray.getFloat(R.styleable.PioArcCircle_thickness1, this.mThickness);
this.mRotate = typedArray.getInt(R.styleable.PioArcCircle_rotate, this.mRotate);
this.mCircleSweepAngle = typedArray.getInt(R.styleable.PioArcCircle_circleSweepAngle, this.mCircleSweepAngle);
this.mCircleEndAngle = typedArray.getInt(R.styleable.PioArcCircle_circleEndAngle, this.mCircleEndAngle);
this.mCircleStartAngle = typedArray.getInt(R.styleable.PioArcCircle_circleStartAngle, this.mCircleStartAngle);
this.mCircleBgColor = typedArray.getInt(R.styleable.PioArcCircle_circleBgColor, this.mCircleBgColor);
this.mEraserColor = typedArray.getInt(R.styleable.PioArcCircle_eraserColor, this.mEraserColor);
this.mEraserInnerBackground = typedArray.getBoolean(R.styleable.PioArcCircle_eraserInnerBackground, this.mEraserInnerBackground);
this.mMinValue = typedArray.getFloat(R.styleable.PioArcCircle_minValue, this.mMinValue);
this.mMaxValue = typedArray.getFloat(R.styleable.PioArcCircle_maxValue, this.mMaxValue);
this.mEnabled = typedArray.getBoolean(R.styleable.PioArcCircle_enable, this.mEnabled);
this.mDotSize = typedArray.getFloat(R.styleable.PioArcCircle_dotSize, this.mDotSize);
this.mTouchInside = typedArray.getBoolean(R.styleable.PioArcCircle_touchInside, this.mTouchInside);
this.mCircleColor = typedArray.getInt(R.styleable.PioArcCircle_circleBgColor, this.mCircleColor);
}
mCircleBgPaint = new Paint();
mCircleBgPaint.setAntiAlias(true);
mCircleBgPaint.setColor(mCircleBgColor);
mCirclePaint = new Paint();
mCirclePaint.setAntiAlias(true);
mCirclePaint.setColor(mCircleColor);
mEraserPaint = new Paint();
mEraserPaint.setAntiAlias(true);
mEraserPaint.setColor(mEraserColor);
if (mEraserInnerBackground) {
mEraserPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
}
mCircleThumbPaint = new Paint();
mCircleThumbPaint.setAntiAlias(true);
mCircleThumbPaint.setColor(Color.CYAN);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
if (w != oldw || h != oldh) {
mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
mBitmap.eraseColor(Color.TRANSPARENT);
mCanvas = new Canvas(mBitmap);
}
super.onSizeChanged(w, h, oldw, oldh);
updateBounds();
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int parentWidth = MeasureSpec.getSize(widthMeasureSpec);
int parentHeight = MeasureSpec.getSize(heightMeasureSpec);
int min = Math.min(widthMeasureSpec, heightMeasureSpec);
this.setMeasuredDimension(parentWidth, parentHeight);
this.setTouchInSide(this.mTouchInside);
super.onMeasure(min, min);
}
#Override
protected void onDraw(Canvas canvas) {
mCanvas.drawColor(0, PorterDuff.Mode.CLEAR);
mCanvas.drawArc(mCircleOuterBounds, (mCircleStartAngle + mRotate), (mCircleEndAngle - mCircleStartAngle), true, mCircleBgPaint);
if (mCircleSweepAngle - mRotate > 0f) {
mCanvas.drawArc(mCircleOuterBounds, (mCircleStartAngle + mRotate), (mCircleSweepAngle - mRotate), true, mCirclePaint);
}
mCanvas.drawOval(mCircleInnerBounds, mEraserPaint);
if (mEnabled) {
mThumbXPos = (int) (mTranslateX + (mArcRadius * Math.cos(Math.toRadians((double) this.mCircleSweepAngle))));
mThumbYPos = (int) (mTranslateY + (mArcRadius * Math.sin(Math.toRadians((double) this.mCircleSweepAngle))));
mCanvas.drawCircle(mThumbXPos, mThumbYPos, mThickness, mCircleThumbPaint);
}
canvas.drawBitmap(mBitmap, 0, 0, null);
}
private void updateBounds() {
if (this.getPaddingLeft() < (mThickness / 2)) {
this.setPadding((int) (mThickness / 2), this.getPaddingTop(), this.getPaddingRight(), this.getPaddingBottom());
}
mCircleOuterBounds = new RectF(0 + this.getPaddingLeft(), 0 + this.getPaddingLeft(), getWidth() - this.getPaddingLeft(), getHeight() - this.getPaddingLeft());
mCircleInnerBounds = new RectF(
mCircleOuterBounds.left + mThickness,
mCircleOuterBounds.top + mThickness,
mCircleOuterBounds.right - mThickness,
mCircleOuterBounds.bottom - mThickness);
this.mTranslateX = mCircleOuterBounds.centerX();
this.mTranslateY = mCircleOuterBounds.centerY();
this.mArcRadius = (int) (mTranslateX - this.getPaddingLeft() - (mThickness / 2));
invalidate();
}
#Override
public boolean onTouchEvent(MotionEvent event) {
if (this.mEnabled) {
this.getParent().requestDisallowInterceptTouchEvent(true);
switch (event.getAction()) {
case 0:
this.onStartTrackingTouch();
this.updateOnTouch(event);
break;
case 1:
this.onStopTrackingTouch();
this.setPressed(false);
this.getParent().requestDisallowInterceptTouchEvent(false);
break;
case 2:
this.updateOnTouch(event);
break;
case 3:
this.onStopTrackingTouch();
this.setPressed(false);
this.getParent().requestDisallowInterceptTouchEvent(false);
}
return true;
} else {
return false;
}
}
public void setTouchInSide(boolean isEnabled) {
int thumbHalfheight = (int) (mThickness / 2);
int thumbHalfWidth = (int) (mThickness / 2);
this.mTouchInside = isEnabled;
if (this.mTouchInside) {
this.mTouchIgnoreRadius = (float) this.mArcRadius / 4.0F;
} else {
this.mTouchIgnoreRadius = (float) (this.mArcRadius - Math.min(thumbHalfWidth, thumbHalfheight));
}
}
private void updateOnTouch(MotionEvent event) {
boolean ignoreTouch = this.ignoreTouch(event.getX(), event.getY());
if (!ignoreTouch) {
this.setPressed(true);
this.mProgressSweep = (float) this.getTouchDegrees(event.getX(), event.getY());
this.updateProgress((int) this.mProgressSweep);
}
}
private double getTouchDegrees(float xPos, float yPos) {
double angle = (int) (Math.atan2(yPos - mTranslateY, xPos - mTranslateX) * 180 / Math.PI);
if (angle < 0) {
angle += 360;
}
float x = xPos - this.mTranslateX;
float y = yPos - this.mTranslateY;
angle = Math.toDegrees(Math.atan2((double) y, (double) x) + 1.5707963267948966D - Math.toRadians((double) this.mRotate));
if (angle < 0.0D) {
angle += 360.0D;
}
angle -= (double) this.mCircleStartAngle;
return angle;
}
private boolean ignoreTouch(float xPos, float yPos) {
boolean ignore = false;
double touchRadius = Math.sqrt(Math.pow(xPos - this.mTranslateX, 2) + Math.pow(yPos - this.mTranslateY, 2));
if (this.mTouchInside && touchRadius > this.mArcRadius) {
ignore = true;
} else {
if ((touchRadius > (this.mArcRadius + (this.mThickness / 2))) ||
(touchRadius < (this.mArcRadius - (this.mThickness / 2)))) {
ignore = true;
}
}
return ignore;
}
private void onStartTrackingTouch() {
if (this.mOnPioArcCircleChangeListener != null) {
this.mOnPioArcCircleChangeListener.onStartTrackingTouch(this);
}
}
private void onStopTrackingTouch() {
if (this.mOnPioArcCircleChangeListener != null) {
this.mOnPioArcCircleChangeListener.onStopTrackingTouch(this);
}
}
private void updateProgress(int progress) {
if (progress != INVALID_PROGRESS_VALUE) {
if (this.mOnPioArcCircleChangeListener != null) {
this.mOnPioArcCircleChangeListener.onProgressChanged(this);
}
mCircleSweepAngle = progress;
this.invalidate();
}
}
public OnPioArcCircleChangeListener getmOnPioArcCircleChangeListener() {
return mOnPioArcCircleChangeListener;
}
public void setmOnPioArcCircleChangeListener(OnPioArcCircleChangeListener mOnPioArcCircleChangeListener) {
this.mOnPioArcCircleChangeListener = mOnPioArcCircleChangeListener;
}
public interface OnPioArcCircleChangeListener {
void onProgressChanged(PioArcCircle var1);
void onStartTrackingTouch(PioArcCircle var1);
void onStopTrackingTouch(PioArcCircle var1);
}
}
activity_main.xml:
<com.test.myapplication.PioArcCircle
android:layout_width="200dp"
android:layout_height="200dp"
android:padding="#dimen/activity_vertical_margin"
android:progressDrawable="#drawable/circular_progress_bar"
pioarccircle:circleColor="#color/colorAccent"
pioarccircle:enable="true"
pioarccircle:minValue="50.0"
pioarccircle:rotate="135"
pioarccircle:thickness1="100" />
First problem:
How i can create a few colors of progress?
Thanks for help.
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"