Set Canvas Width and Height Android for Custom View - android

I have an issue with a CustomView. I have a layout where I have EditText fields on top of screen. At the bottom there are two buttons. The remaining space in the middle of the screen is occupied with an ImageView. On the ImageView I should be able to draw a rectangle. I have kept a CustomView in my layout which also occupied the same width and height as that of ImageView. But my issue is the canvas occupies the whole width and height of a screen. So when user draws a rectangle on my image it hides below my EditText fields. I want to limit my canvas size same as that of the ImageSize and not to hide.
I have checked some sources but it did not help me.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/white" >
<RelativeLayout
android:id="#+id/headerLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="10dp"
android:background="#color/header_red" >
<TextView
android:id="#+id/tvAddName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_marginTop="10dp"
android:layout_marginLeft="10dp"
android:text="Enter Name"
android:textColor="#color/white"
android:textSize="16sp" />
<TextView
android:id="#+id/tvName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#id/tvAddDimens"
android:layout_marginTop="5dp"
android:layout_alignParentLeft="true"
android:layout_marginLeft="10dp"
android:text="Name:"
android:textColor="#color/white"
android:textSize="16sp" />
<EditText
android:id="#+id/etNameValue"
android:layout_width="80dp"
android:layout_height="20dp"
android:layout_marginLeft="10dp"
android:layout_below="#id/tvAddDimens"
android:layout_marginTop="5dp"
android:layout_toRightOf="#id/tvWidth"
android:paddingLeft="5dp"
android:paddingTop="2dp"
android:singleLine="true"
android:paddingBottom="2dp"
android:background="#FFFFFF"
android:maxLength="8"
android:textColor="#color/black"
android:textSize="16sp" />
</RelativeLayout>
<RelativeLayout
android:id="#+id/bottomLayout"
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_alignParentBottom="true"
android:background="#color/dark_gray" >
<ImageView
android:id="#+id/ivDelete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:layout_marginLeft="50dp"
android:src="#drawable/delete" />
<ImageView
android:id="#+id/ivOk"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="50dp"
android:src="#drawable/tick" />
</RelativeLayout>
<RelativeLayout android:id="#+id/imgLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#id/bottomLayout"
android:layout_below="#id/headerLayout"
android:layout_marginBottom="10dp"
android:layout_marginTop="10dp" >
<ImageView
android:id="#+id/ivCapturedImg"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:scaleType="fitXY" />
<com.ibee.macromedia.utils.DrawingView
android:id="#+id/drawRect"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="10dp" />
</RelativeLayout>
</RelativeLayout>
My DrawingView class is:
public class DrawingView extends View {
/** Need to track this so the dirty region can accommodate the stroke. **/
private static final float STROKE_WIDTH = 5f;
public Paint paint;
/**
* Optimizes painting by invalidating the smallest possible area.
*/
private int mStartX = 0;
private int mStartY = 0;
private int mEndX = 0;
private int mEndY = 0;
private boolean isDraw=false;
private Context mContext;
public DrawingView(Context context, AttributeSet attrs) {
super(context, attrs);
this.mContext=context;
init();
}
public void init(){
paint=new Paint();
paint.setAntiAlias(true);
paint.setColor(mContext.getResources().getColor(R.color.fluor));
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(STROKE_WIDTH);
}
/**
* Erases the signature.
*/
public void clear() {
isDraw=true;
paint=new Paint();
paint.setAntiAlias(true);
paint.setColor(Color.TRANSPARENT);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(STROKE_WIDTH);
invalidate();
}
#Override
protected void onDraw(Canvas canvas) {
Log.e("MACROMEDIA", " DRAWING VIEW CANVAS WIDTH " + canvas.getWidth() + " HEIGTH " + canvas.getHeight());
if(isDraw==true){
paint = new Paint();
paint.setColor(Color.TRANSPARENT);
canvas.drawRect(Math.min(mStartX, mEndX), Math.min(mStartY, mEndY),
Math.max(mEndX, mStartX), Math.max(mEndY, mStartY), paint);
} else{
paint=new Paint();
paint.setAntiAlias(true);
paint.setColor(mContext.getResources().getColor(R.color.fluor));
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(STROKE_WIDTH);
canvas.drawRect(Math.min(mStartX, mEndX), Math.min(mStartY, mEndY),
Math.max(mEndX, mStartX), Math.max(mEndY, mStartY), paint);
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
float eventX = event.getX();
float eventY = event.getY();
isDraw=false;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mStartX = (int) event.getX();
mStartY = (int) event.getY();
return true;
case MotionEvent.ACTION_MOVE:
final int x = (int) event.getX();
final int y = (int) event.getY();
if (Math.abs(x - mEndX) > 5 || Math.abs(y - mEndY) > 5) {
mEndX = x;
mEndY = y;
invalidate();
}
break;
case MotionEvent.ACTION_UP:
break;
default:
return false;
}
invalidate();
return true;
}
}
Please help me. Thanks

Try in your xml:
<com.ibee.macromedia.utils.DrawingView
android:id="#+id/drawRect"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="#+id/ivCapturedImg"
android:layout_alignBottom="#+id/ivCapturedImg"
android:layout_alignLeft="#+id/ivCapturedImg"
android:layout_alignRight="#+id/ivCapturedImg" />
This should align all the borders of your custom view to the borders of the ImageView.

Related

Why are buttons making my canvas drawing like hexagon shape in Android?

I have a strange problem I'm creating a canvas drawing app in Android that has lots of buttons in xml file. The problems is when I draw a circle with all those buttons included in the file it's never a smooth circle it's full of corners like hexagon shape but when I exclude buttons may be leaving in one or two, it draws a perfect smooth circle. I have tried to split the file into three so I've included them using but still same result. Can someone please enlighten me what am I do wrong.
<?xml version="1.0" encoding="utf-8"?>
<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=".MainActivity">
<!--First Draw -->
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:openDrawer="start">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ImageButton
android:id="#+id/nav_one"
android:layout_width="30dp"
android:layout_height="60dp"
android:layout_marginTop="100dp"
android:layout_marginBottom="100dp"
android:background="#drawable/ic_tab_res_bkg"/>
<ImageButton
android:id="#+id/nav_two"
android:layout_width="30dp"
android:layout_height="60dp"
android:layout_marginTop="200dp"
android:background="#drawable/ic_tab_tools_bkg"/>
</LinearLayout>
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<!-- The navigation drawer -->
<ListView android:id="#+id/resource_bank"
android:layout_width="350dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:divider="#android:color/background_light"
android:dividerHeight="0dp"
android:background="#f4f1f1"
/>
<ListView android:id="#+id/tools"
android:layout_width="350dp"
android:layout_height="match_parent"
android:layout_gravity="end"
android:choiceMode="singleChoice"
android:divider="#android:color/background_light"
android:dividerHeight="0dp"
android:background="#dedada"/>
</android.support.v4.widget.DrawerLayout>
<RelativeLayout
android:id="#+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center" >
<xxxxx.xxxxxx.xxxx.xxxxxx.DrawView
android:id="#+id/canvas_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/canvas_view">
<!-- Pen icons -->
<include layout="#layout/activity_pen_color" android:id="#+id/pen_color" />
<include layout="#layout/activity_pen_style" android:id="#+id/pen_style" />
<!-- Navigation bar icons -->
<ImageView
android:id="#+id/icon_bar"
android:layout_width="match_parent"
android:layout_height="70dp"
android:layout_gravity="bottom"
android:background="#drawable/icon_bar_bkg"
/>
<Button
android:id="#+id/ic_select"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginLeft="150dp"
android:layout_marginTop="60dp"
android:elevation="1dp"
android:background="#drawable/ic_select_bkg"/>
<TextView
android:id="#+id/text_select"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="150dp"
android:layout_marginTop="90dp"
android:text="Select"
android:textColor="#color/colorAccent"
/>
<Button
android:id="#+id/ic_pens"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_marginLeft="200dp"
android:layout_marginTop="60dp"
android:elevation="1dp"
android:background="#drawable/ic_pen_bkg"/>
<TextView
android:id="#+id/text_pens"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="200dp"
android:layout_marginTop="90dp"
android:text="Pen"
android:textColor="#color/colorAccent"
/>
</FrameLayout>
</RelativeLayout>
My DrawView
public class DrawView extends View {
private Paint drawPaint, canvasPaint;
private Canvas drawCanvas;
private Bitmap canvasBitmap;
private SparseArray<Path> paths;
public DrawView(Context context) {
super(context);
setupDrawing();
}
public DrawView(Context context, AttributeSet attrs) {
super(context, attrs);
setupDrawing();
}
public DrawView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
setupDrawing();
}
private void setupDrawing() {
paths = new SparseArray<>();
drawPaint = new Paint();
drawPaint.setColor(Color.BLACK);
drawPaint.setAntiAlias(true);
drawPaint.setStrokeWidth(9);
drawPaint.setStyle(Paint.Style.STROKE);
drawPaint.setStrokeJoin(Paint.Join.ROUND);
drawPaint.setStrokeCap(Paint.Cap.ROUND);
canvasPaint = new Paint(Paint.DITHER_FLAG);
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
canvasBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
drawCanvas = new Canvas(canvasBitmap);
}
#Override
protected void onDraw(Canvas canvas) {
canvas.drawBitmap(canvasBitmap, 0, 0, canvasPaint);
for (int i=0; i<paths.size(); i++) {
canvas.drawPath(paths.valueAt(i), drawPaint);
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
int index = event.getActionIndex();
int id = event.getPointerId(index);
Path path;
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_POINTER_DOWN:
path = new Path();
path.moveTo(event.getX(index), event.getY(index));
paths.put(id, path);
break;
case MotionEvent.ACTION_MOVE:
for (int i=0; i<event.getPointerCount(); i++) {
id = event.getPointerId(i);
path = paths.get(id);
if (path != null) path.lineTo(event.getX(i), event.getY(i));
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
path = paths.get(id);
if (path != null) {
drawCanvas.drawPath(path, drawPaint);
paths.remove(id);
}
break;
default:
return false;
}
invalidate();
return true;
}
/**
* change path color here
*/
public void setPathColor(int color) {
drawPaint.setColor(color);
}
}
Answer
I take it that you are drawing this circle with your finger, and that when a lot of extra buttons are present, you notice that the lines you draw with your finger become "less smooth".
This is related to the app's screen refresh rate. When your app has to spend lots of time drawing all those extra buttons, it has fewer opportunities to get MotionEvents. With fewer MotionEvents, there are fewer points in your shape, and it takes longer line segments to connect them.
Suggested fix
The recommended approach is to stop those button views from being invalidated (an assumption on my part) every time onTouchEvent() gets called. From your code, I can't immediately see why they would be invalidated, but it may be that your DrawView underlies the buttons you are adding, thus whenever the DrawView is invalidate()-ed, the system must re-compose it with the buttons. You could move the DrawView so that it's by itself. Adding an opaque background to your button container(s) may help as well, b/c the system would have to do fewer alpha calculations.
You must have a lot of buttons... you may want to do some performance profiling to determine exactly what's taking so long.

Programmatically draw lines between buttons on android

I am trying to create a tree graph based on user data. There is no library or anything to help and im just a beginner. I just created 8 image buttons and after the app calculates the data, it needs to draw lines between these nodes to connect them. I have no idea how to use canvas or drawline so any help would be much appreciated.
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_margin="20dp"
android:id="#+id/nodesImages">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:layout_width="30dp"
android:layout_height="30dp"
android:text="1"
android:layout_margin="20dp"
android:id="#+id/node1"
android:background="#drawable/node"/>
<Button
android:layout_width="30dp"
android:layout_height="30dp"
android:text="2"
android:id="#+id/node2"
android:layout_margin="20dp"
android:background="#drawable/node"/>
<Button
android:layout_width="30dp"
android:layout_height="30dp"
android:text="5"
android:id="#+id/node5"
android:layout_margin="20dp"
android:background="#drawable/node"/>
<Button
android:layout_width="30dp"
android:layout_height="30dp"
android:text="6"
android:id="#+id/node6"
android:layout_margin="20dp"
android:background="#drawable/node"/>
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:layout_width="30dp"
android:layout_height="30dp"
android:text="3"
android:layout_margin="20dp"
android:id="#+id/node3"
android:background="#drawable/node"/>
<Button
android:layout_width="30dp"
android:layout_height="30dp"
android:text="4"
android:id="#+id/node4"
android:layout_margin="20dp"
android:background="#drawable/node"/>
<Button
android:layout_width="30dp"
android:layout_height="30dp"
android:text="7"
android:id="#+id/node7"
android:layout_margin="20dp"
android:background="#drawable/node"/>
<Button
android:layout_width="30dp"
android:layout_height="30dp"
android:text="8"
android:id="#+id/node8"
android:layout_margin="20dp"
android:background="#drawable/node"/>
![enter image description here][1]</LinearLayout>
Edit - DrawView Class
How can I use this DrawView class to add the lines?
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.View;
public class DrawView extends View
{
Paint paint = new Paint();
static int startX, startY, endX, endY;
public DrawView(Context context,int startX, int startY, int endX, int endY)
{
super(context);
this.startX = startX;
this.startY = startY;
this.endX = endX;
this.endY = endY;
paint.setColor(Color.BLACK);
}
public DrawView(Context context)
{
super(context);
paint.setColor(Color.BLACK);
}
#Override
public void onDraw(Canvas canvas)
{
canvas.drawLine(startX, startY, endX, endY,paint);
}
}
Edit 2:
This is not working for some reason:
LinearLayout myLayout = (LinearLayout) findViewById(R.id.nodesImages);
DrawView drawView = new DrawView(getApplicationContext(),(int)node1.getX(),(int)node1.getY(),(int)node2.getX(),(int)node2.getY());
myLayout.addView(drawView);
Edit 3
There are so many libraries for creating complex graphs (line,bar,scatter,etc) . Why can't somebody create a library for tree graphs???? seems easy for those people!!!
based on your provide width and height of your button in layout. I use translation to do that. See the below code and the ugly Image for explain ##!
LinearLayout nodesImages = (LinearLayout) findViewById(R.id.nodesImages);
View v = new View(this); //this, because I write this code in the Activity class
//yah, try to understand values 20, 30,...
v.setLayoutParams(new ViewGroup.LayoutParams(dpToPx(20+20),dpToPx(2)));
v.setBackgroundColor(Color.BLACK);
nodesImages.addView(v);
v.setTranslationY(-dpToPx(30+20+20)-dpToPx(20+30/2));
v.setTranslationX(dpToPx(20+30));
with:
private int dpToPx(int dp) {
return (int) (dp * getResources().getDisplayMetrics().density + 0.5f);
}
Ugly Image for explain:
UPDATE get location of view:
final LinearLayout nodesImages = (LinearLayout) findViewById(R.id.nodesImages);
//using addOnGlobalLayoutListener to make sure layout is happened.
nodesImages.getViewTreeObserver().addOnGlobalLayoutListener(
new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
//Remove the listener before proceeding
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
nodesImages.getViewTreeObserver().removeOnGlobalLayoutListener(this);
} else {
nodesImages.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
Button node1 = (Button)findViewById(R.id.node1);
int[] loc1 = new int[2];
node1.getLocationInWindow(loc1);//loc1[0] is x and loc1[1] is y
//for more information about this method, in Android Studio, just right-click -> Go To -> Declaration
Button node2 = (Button)findViewById(R.id.node2);
int[] loc2 = new int[2];
node2.getLocationInWindow(loc2);
View v = new View(getApplication());
v.setLayoutParams(new ViewGroup.LayoutParams(loc2[0]-loc1[0]-node1.getWidth(),dpToPx(2)));//dpToPx(20 + 20), dpToPx(2)));
v.setBackgroundColor(Color.BLACK);
nodesImages.addView(v);
v.setTranslationY(-dpToPx(30+20+20)-dpToPx(20+30/2));
v.setTranslationX(dpToPx(20+30));
}
}
);
Psst... Just do it in XML
<View
android:layout_height="1dp"
android:layout_width="match_parent"
android:background="#android:color/black"/>

Scrolling the custom views - Android

Below is the image of the menu I need to make.
I have drawn the triangles using canvas in custom views. I also need to scroll this menu, when custom views are added in the scroll view it takes each View as a rectangular item not allowing the triangles to be drawn like this.
Is there anyway to achieve this?
Thanks in advance.
At first you must create 2 custom views, with different draws of triangles. Then in your RelativeLayout or another create those triangles and set the, negative margin_top value for correct presentation, like in my example:
So, now lets look at code.
Dont critic my code. It`s just example for you without true OOP structure :)
CustomShapeLeft.class:
/**
* Created by gigamole on 07.02.15.
*/
public class CustomShapeLeft extends RelativeLayout {
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
int backgroundColor;
int viewWidth; // width of parent(CustomShape layout)
int viewHeight;
public CustomShapeLeft(Context context) {
super(context);
this.setWillNotDraw(false);
}
public CustomShapeLeft(Context context, AttributeSet attrs) {
super(context, attrs);
this.setWillNotDraw(false);
TypedArray ta = context.obtainStyledAttributes(attrs, new int[]{android.R.attr.background});
this.backgroundColor = ((ColorDrawable) ta.getDrawable(0)).getColor();
this.setBackgroundColor(Color.TRANSPARENT);
}
public CustomShapeLeft(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.setWillNotDraw(false);
}
#Override
protected void onSizeChanged(int xNew, int yNew, int xOld, int yOld) {
super.onSizeChanged(xNew, yNew, xOld, yOld);
viewWidth = xNew;
viewHeight = yNew;
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
Path path = new Path();
Point[] points = new Point[3];
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
paint.setColor(backgroundColor);
paint.setStyle(Paint.Style.FILL);
points[0] = new Point(0, 0);
points[1] = new Point(viewWidth, (viewHeight / 2));
points[2] = new Point(0, (viewHeight));
path.setFillType(Path.FillType.EVEN_ODD);
path.moveTo(points[0].x, points[0].y);
path.lineTo(points[1].x, points[1].y);
path.lineTo(points[2].x, points[2].y);
path.close();
canvas.drawPath(path, paint);
}
public boolean isTouched(final float X, final float Y){
final Polygon p = new Polygon(points);
return p.contains(X, Y);
}
}
Method isTouched() need for know when the user tap on shape, but not on View, cause when on last, its problematic to take correct action, cause they lay down like layer-layer-layer system.
This method get the position of tap and calculate is on shape or not. In your way you will dont have onClickListener, just onTouchListener.
CustomShapeRight.class:
They are almost similar, but different draw methods:
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
paint.setColor(backgroundColor);
paint.setStyle(Paint.Style.FILL);
points[0] = new Point(viewWidth, 0);
points[1] = new Point(0, (viewHeight / 2));
points[2] = new Point(viewWidth, (viewHeight));
path.setFillType(Path.FillType.EVEN_ODD);
path.moveTo(points[0].x, points[0].y);
path.lineTo(points[1].x, points[1].y);
path.lineTo(points[2].x, points[2].y);
path.close();
canvas.drawPath(path, paint);
}
Layout.xml:
<null_anal.customshape.CustomShapeLeft
android:layout_width="match_parent"
android:layout_height="70dp"
android:id="#+id/triangle_1"
android:background="#android:color/holo_red_dark">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:textSize="22dp"
android:padding="5dp"
android:textColor="#android:color/black"
android:text="MEN"
android:background="#android:color/transparent"/>
</null_anal.customshape.CustomShapeLeft>
<null_anal.customshape.CustomShapeRight
android:layout_width="match_parent"
android:layout_height="70dp"
android:id="#+id/triangle_2"
android:layout_marginTop="-36dp"
android:background="#android:color/holo_orange_dark"
android:layout_below="#+id/triangle_1">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:textSize="22dp"
android:layout_alignParentRight="true"
android:padding="5dp"
android:textColor="#android:color/black"
android:text="HOME"
android:background="#android:color/transparent"/>
</null_anal.customshape.CustomShapeRight>
<null_anal.customshape.CustomShapeLeft
android:layout_width="match_parent"
android:layout_height="70dp"
android:id="#+id/triangle_3"
android:layout_marginTop="-36dp"
android:background="#android:color/holo_purple"
android:layout_below="#+id/triangle_2">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:textSize="22dp"
android:padding="5dp"
android:textColor="#android:color/black"
android:text="WOMEN"
android:background="#android:color/transparent"/>
</null_anal.customshape.CustomShapeLeft>
<null_anal.customshape.CustomShapeRight
android:layout_width="match_parent"
android:layout_height="70dp"
android:id="#+id/triangle_4"
android:layout_marginTop="-36dp"
android:background="#android:color/holo_green_dark"
android:layout_below="#+id/triangle_3">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:textSize="22dp"
android:layout_alignParentRight="true"
android:padding="5dp"
android:textColor="#android:color/black"
android:text="ART"
android:background="#android:color/transparent"/>
</null_anal.customshape.CustomShapeRight>
<null_anal.customshape.CustomShapeLeft
android:layout_width="match_parent"
android:layout_height="70dp"
android:id="#+id/triangle_5"
android:layout_marginTop="-36dp"
android:background="#android:color/holo_blue_dark"
android:layout_below="#+id/triangle_4">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:textSize="22dp"
android:padding="5dp"
android:textColor="#android:color/black"
android:text="KIDS"
android:background="#android:color/transparent"/>
</null_anal.customshape.CustomShapeLeft>
<null_anal.customshape.CustomShapeRight
android:layout_width="match_parent"
android:layout_height="70dp"
android:id="#+id/triangle_6"
android:layout_marginTop="-36dp"
android:background="#android:color/holo_blue_bright"
android:layout_below="#+id/triangle_5">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:textSize="22dp"
android:layout_alignParentRight="true"
android:padding="5dp"
android:textColor="#android:color/black"
android:text="MUSIC"
android:background="#android:color/transparent"/>
</null_anal.customshape.CustomShapeRight>
And in activity set them onTouchListener():
CustomShapeRight customShapeRight = (CustomShapeRight) findViewById(R.id.triangle_6);
customShapeRight.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (((CustomShapeRight)v).isTouched(event.getX(), event.getY())) {
Toast.makeText(getApplicationContext(), ((TextView)((CustomShapeRight) v).getChildAt(0)).getText(), Toast.LENGTH_SHORT).show();
}
return false;
}
});
And all. I`d hope this will help you and with delete items "X" item in your layout you will deal with it alone. And thanks for cool question. Like it.

How to draw a circle in center in android

I want the circular image to be in the centre.
How to have it in the centre of the device?
I don't want to use a relative layout. I have all ready tried that, but it needs a hard coded value for the circle; hence. it won't work on all the devices.
I am trying to achieve it by LinearLayout (using android:layout_weight property)
I have tried android:layout_gravity="center",android:gravity="center"
but the circle still won't make it to the centre.
I have attached the screen for reference
I want the circle to be in parent center
My xml is:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res/com.example.dd"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:orientation="vertical" >
<LinearLayout
android:id="#+id/LinearLayout02"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:orientation="horizontal" >
<Button
android:id="#+id/Button04"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="left1" >
</Button>
<com.example.dd.CircularImageView
android:id="#+id/round"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:src="#drawable/buttonarea"
app:border="true"
app:border_color="#323232"
app:border_width="55dp"
app:shadow="true" />
<Button
android:id="#+id/Button08"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="right" >
</Button>
</LinearLayout>
</LinearLayout>
My circular class is:
public class CircularImageView extends ImageView {
private int borderWidth;
private int canvasSize;
private Bitmap image;
private Paint paint;
private Paint paintBorder;
public CircularImageView(final Context context) {
this(context, null);
}
public CircularImageView(Context context, AttributeSet attrs) {
this(context, attrs, R.attr.circularImageViewStyle);
}
public CircularImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// init paint
paint = new Paint();
paint.setAntiAlias(true);
paintBorder = new Paint();
paintBorder.setAntiAlias(true);
// load the styled attributes and set their properties
TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.CircularImageView, defStyle, 0);
if(attributes.getBoolean(R.styleable.CircularImageView_border, true)) {
int defaultBorderSize = (int) (4 * getContext().getResources().getDisplayMetrics().density + 0.5f);
setBorderWidth(attributes.getDimensionPixelOffset(R.styleable.CircularImageView_border_width, defaultBorderSize));
setBorderColor(attributes.getColor(R.styleable.CircularImageView_border_color, Color.WHITE));
}
if(attributes.getBoolean(R.styleable.CircularImageView_shadow, false))
addShadow();
}
public void setBorderWidth(int borderWidth) {
Log.d("TAG","::::::::::::borderWidth"+borderWidth);
this.borderWidth = borderWidth;
this.requestLayout();
this.invalidate();
}
public void setBorderColor(int borderColor) {
if (paintBorder != null)
paintBorder.setColor(borderColor);
this.invalidate();
}
public void addShadow() {
setLayerType(LAYER_TYPE_SOFTWARE, paintBorder);
paintBorder.setShadowLayer(4.0f, 0.0f, 2.0f, Color.BLACK);
}
#Override
public void onDraw(Canvas canvas) {
// load the bitmap
image = drawableToBitmap(getDrawable());
// init shader
if (image != null) {
canvasSize = canvas.getWidth();
Log.d("TAG","::::::::::::canvasSize"+canvasSize);
if(canvas.getHeight()<canvasSize)
canvasSize = canvas.getHeight();
BitmapShader shader = new BitmapShader(Bitmap.createScaledBitmap(image, canvasSize, canvasSize, false), Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
paint.setShader(shader);
// 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
int circleCenter = (canvasSize - (borderWidth * 2)) / 2;
canvas.drawCircle(circleCenter + borderWidth, circleCenter + borderWidth, ((canvasSize - (borderWidth * 2)) / 2) + borderWidth - 4.0f, paintBorder);
canvas.drawCircle(circleCenter + borderWidth, circleCenter + borderWidth, ((canvasSize - (borderWidth * 2)) / 2) - 4.0f, paint);
}
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = measureWidth(widthMeasureSpec);
int height = measureHeight(heightMeasureSpec);
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) {
// The parent has determined an exact size for the child.
result = specSize;
} else if (specMode == MeasureSpec.AT_MOST) {
// The child can be as large as it wants up to the specified size.
result = specSize;
} else {
// The parent has not imposed any constraint on the child.
result = canvasSize;
}
return result;
}
private int measureHeight(int measureSpecHeight) {
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 if (specMode == MeasureSpec.AT_MOST) {
// The child can be as large as it wants up to the specified size.
result = specSize;
} else {
// Measure the text (beware: ascent is a negative number)
result = canvasSize;
}
return (result + 2);
}
public Bitmap drawableToBitmap(Drawable drawable) {
if (drawable == null) {
return null;
} else if (drawable instanceof BitmapDrawable) {
return ((BitmapDrawable) drawable).getBitmap();
}
Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(),
drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
}
my attrs.xml goes in values:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="CircularImageView">
<attr name="border" format="boolean"></attr>
<attr name="border_width" format="dimension"></attr>
<attr name="border_color" format="color"></attr>
<attr name="shadow" format="boolean"></attr>
</declare-styleable>
<declare-styleable name="Theme">
<attr name="circularImageViewStyle" format="reference"></attr>
</declare-styleable>
</resources>
Use some fake layouts and set the visibility to invisible. This should do the trick.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res/com.example.dd"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:orientation="vertical" >
<LinearLayout
android:id="#+id/LinearLayout02"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:orientation="horizontal" >
<Button
android:id="#+id/Button04"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="left1" >
</Button>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical" >
<Button
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical"
android:text="dummy"
android:visibility="invisible" >
</Button>
<Button
android:id="#+id/round"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#android:drawable/star_on"
app:shadow="true" />
<Button
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical"
android:text="dummy"
android:visibility="invisible" >
</Button>
</LinearLayout>
<Button
android:id="#+id/Button08"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="right" >
</Button>
</LinearLayout>
</LinearLayout>
try this
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res/com.example.dd"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:orientation="vertical" >
<LinearLayout
android:id="#+id/LinearLayout02"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_gravity="center"
android:orientation="horizontal" >
<Button
android:id="#+id/Button04"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="left1" >
</Button>
<com.example.dd.CircularImageView
android:id="#+id/round"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:src="#drawable/buttonarea"
android:layout_gravity="center"
app:border="true"
app:border_color="#323232"
app:border_width="55dp"
app:shadow="true" />
<Button
android:id="#+id/Button08"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="right" >
</Button>
</LinearLayout>
Try this:
<com.example.dd.CircularImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/myCircularImageView"
android:src="#drawable/buttonarea"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"/>
One way to do it would be to set your LinearLayout height to match_parent, then set the layout_gravity on the circle to center_vertical.
EDIT: Just tested, this works for me:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:orientation="vertical">
<LinearLayout
android:id="#+id/LinearLayout02"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:orientation="horizontal">
<Button
android:id="#+id/Button04"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="left1">
</Button>
<com.example.dd.CircularImageView
android:id="#+id/round"
android:layout_width="fill_parent"
android:layout_gravity="center_vertical"
android:layout_height="wrap_content"
android:background="#android:color/black"
android:layout_weight="1"/>
<Button
android:id="#+id/Button08"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="right">
</Button>
</LinearLayout>
</LinearLayout>
Ignore the background color and missing app: attributes, the general idea stays the same.

How disable ScrollView

I have a layout where I have a ScrollView and some stuffs. It looks like:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/welcome_scrol_lay"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:background="#drawable/bg">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="#drawable/bg"
android:weightSum="100" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="250dp"
android:orientation="vertical"
android:weightSum="100"
android:background="#drawable/specialmapholder">
<android.support.v4.view.ViewPager
android:id="#+id/welcomeViewPager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginTop="15dp"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:layout_weight="90"
android:clickable="true" />
<LinearLayout
android:id="#+id/welcome_indicatorLayout"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="10"
android:gravity="center" >
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="50"
android:orientation="vertical">
<TextView
android:id="#+id/welcome_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:text="Large Text"
android:textColor="#color/white"
android:textStyle="bold"
android:textSize="26dp"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="#+id/welcome_body"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:text="Medium Text"
android:textColor="#color/white"
android:textSize="14dp"
android:textStyle="bold"
android:layout_marginTop="20dp"
android:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout>
</LinearLayout>
</ScrollView>
As you can see I have a Viewpager in the ScrollView. I want to disable scroll when I touch ViewPager, because when I want to change picture page is scrolled. How can I disable the scroll function when I touch the ViewPager?
In Android, parents can consume child's TouchEvents. In this case, the ScrollView consumes the TouchEvents of your ViewPager component. To avoid this behaviour, Android framework provides the onInterceptTouchEvent(MotionEvent).
In your case, you have to subclass ScrollView and change the onInterceptTouchEvent(MotionEvent) method. You should change the onInterceptTouchEvent(MotionEvent), so that the ScrollView consumes the child's event only when the user scrolls the ScrollView vertically.
example implementation for ListView:
public class VerticalListView extends ListView {
private float mLastX;
private float mLastY;
private float mDiffX;
private float mDiffY;
public VerticalListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public VerticalListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public VerticalListView(Context context) {
super(context);
}
#Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
// reset difference values
mDiffX = 0;
mDiffY = 0;
mLastX = ev.getX();
mLastY = ev.getY();
break;
case MotionEvent.ACTION_MOVE:
final float curX = ev.getX();
final float curY = ev.getY();
mDiffX += Math.abs(curX - mLastX);
mDiffY += Math.abs(curY - mLastY);
mLastX = curX;
mLastY = curY;
// don't intercept event, when user tries to scroll horizontally
if (mDiffX > mDiffY) {
return false;
}
}
return super.onInterceptTouchEvent(ev);
}
}

Categories

Resources