RadioGroup not display correct - android

I have use class RadioButtonCenter at
https://github.com/pizza/MaterialTabs/blob/master/sample/src/io/karim/materialtabs/sample/ui/RadioButtonCenter.java
It worked good in below API 24. But in API 24, It not display correct.
when i click tab new. tab old always active. When I intent to activity diff and back. It display correct.
I did not find the problem. Please. Help me!
This is xml
<RadioGroup
android:id="#+id/bottom_navigation_on_main"
android:layout_width="match_parent"
android:layout_height="#dimen/item_height"
android:layout_alignParentBottom="true"
android:orientation="horizontal"
android:weightSum="4">
<RadioButtonCenter
android:id="#+id/tab_home"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:background="#drawable/selector_tab_main"
android:button="#null"
android:clickable="true"
android:gravity="center"
app:radioDrawable="#drawable/selector_tab_home" />
<RadioButtonCenter
android:id="#+id/tab_search"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:button="#null"
android:clickable="true"
android:background="#drawable/selector_tab_main"
android:gravity="center"
app:radioDrawable="#drawable/selector_tab_search" />
</RadioGroup>
This is selector
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="#drawable/ic_home_on" android:state_checked="true"
/>
<item android:drawable="#drawable/ic_home_on" android:state_activated="true"
/>
<item android:drawable="#drawable/ic_home_off" />
</selector>

I found the problem. I add requestLayout(); and now It worked !
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (buttonDrawable != null) {
if (Build.VERSION.SDK_INT >= 24){
requestLayout();
}
buttonDrawable.setState(getDrawableState());
final int verticalGravity = getGravity() & Gravity.VERTICAL_GRAVITY_MASK;
final int height = buttonDrawable.getIntrinsicHeight();
int y = 0;
switch (verticalGravity) {
case Gravity.BOTTOM:
y = getHeight() - height;
break;
case Gravity.CENTER_VERTICAL:
y = (getHeight() - height) / 2;
break;
}
int buttonWidth = buttonDrawable.getIntrinsicWidth();
int buttonLeft = (getWidth() - buttonWidth) / 2;
buttonDrawable.setBounds(buttonLeft, y, buttonLeft + buttonWidth, y + height);
buttonDrawable.draw(canvas);
}
}

Related

Increase LinearLayout width from either right or left

I have a LinearLayout which is centered on the screen. It has a width less than the screen width. There are two buttons: Right-Arrow and Left-Arrow.
When the user presses the relevant button, the layout should increase its width from the relevant side. The other side should keep its position there.
Right now setting the width increases the layout from both sides equally. The layout needs to be initially centered and it has to expand from either side by user's input. (Use case is to find the width of relevant part of an image whose right and left sides have unequal borders, so the user has to mark them using my technique).
I am using following to increase width but it has the behaviour described above.
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams)
llCropOverlay.getLayoutParams();
params.width = params.width + 1;
PS: This functionality was implemented in Tasker app since its early days; so it is possible.
EDIT:
Here is the layout.
<?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:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="vertical">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:gravity="top"
android:layout_gravity="top"
android:id="#+id/iv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="visible" />
<LinearLayout
android:id="#+id/llRightLeft"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center">
<Button
android:id="#+id/bLeft"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="LEFT" />
<Button
android:id="#+id/bRight"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="RIGHT" />
</LinearLayout>
<LinearLayout
android:layout_gravity="center_horizontal"
android:id="#+id/llCropOverlay"
android:layout_width="match_parent"
android:layout_height="70dp"
android:background="#color/colorCropOverlay"
android:orientation="vertical" />
</FrameLayout>
</LinearLayout>
The last LinearLayout (llCropOverlay) should be resized. Note that I am programatically changing the width to 300 before using resizing the buttons so I can test if the buttons are working.
I have found an almost perfect solution (there is sometimes a problem with one pixel which is annoying - any suggestions will be appreciated).
For this, we need some variables set up. Firstly, the LinearLayout called llCropOverlay must be found and identified.
Here is its xml:
<LinearLayout
android:layout_gravity="center_horizontal"
android:id="#+id/llCropOverlay"
android:layout_width="200dp"
android:layout_height="150dp"
android:background="#color/colorCropOverlay"
android:orientation="vertical" />
Now before allowing user to interact we need to find the original position of the llCropOverlay. So use this in OnCreate():
llCropOverlay.post(new Runnable() {
#Override
public void run() {
orgX = llCropOverlay.getX();
}
});
Now set up all the buttons and set a setOnTouchListener() on these buttons. Then when the listener is called, pass the touched button in the following method. Use a Handler and postDelayed() to keep calling this method till the button is pressed. Or call it once to resize by one pixel row/column.
void handleTouchOrClick(View view) {
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams)
llCropOverlay.getLayoutParams();
switch (view.getId()) {
case R.id.bUp:
params.height = params.height - 1;
break;
case R.id.bDown:
params.height = params.height + 1;
break;
case R.id.bRight:
params.width = params.width + 1;
llCropOverlay.post(new Runnable() {
#Override
public void run() {
llCropOverlay.setX(orgX);
}
});
break;
case R.id.bRightContract:
params.width = params.width - 1;
llCropOverlay.post(new Runnable() {
#Override
public void run() {
llCropOverlay.setX(orgX);
}
});
break;
case R.id.bLeft:
params.width = params.width + 1;
orgX--;
llCropOverlay.post(new Runnable() {
#Override
public void run() {
llCropOverlay.setX(orgX);
}
});
break;
case R.id.bLeftContract:
params.width = params.width - 1;
orgX++;
llCropOverlay.post(new Runnable() {
#Override
public void run() {
llCropOverlay.setX(orgX);
}
});
break;
}
llCropOverlay.setLayoutParams(params);
}
Now here's how we actually resize the image:
For ease of users I am cropping it in two steps.
Crop from sides:
ViewGroup.MarginLayoutParams params =
(ViewGroup.MarginLayoutParams) llCropOverlay.getLayoutParams();
float eventX = params.width;
float eventY = 0;
float[] eventXY = new float[]{eventX, eventY};
Matrix invertMatrix = new Matrix();
imageView.getImageMatrix().invert(invertMatrix);
invertMatrix.mapPoints(eventXY);
int x = Integer.valueOf((int) eventXY[0]);
int y = Integer.valueOf((int) eventXY[1]);
int height = params.height;
while (height * 3 > originalBitmap.getHeight()) {
height = height - 10;
}
croppedBitmapByWidth = Bitmap.createBitmap(originalBitmap, (int) orgX, 0,
x, height);
imageView.setImageBitmap(croppedBitmapByWidth);
crop from bottom:
float eventX2 = 0;
float eventY2 = params.height;
float[] eventXY2 = new float[]{eventX2, eventY2};
Matrix invertMatrix2 = new Matrix();
imageView.getImageMatrix().invert(invertMatrix2);
invertMatrix2.mapPoints(eventXY2);
int x2 = Integer.valueOf((int) eventXY2[0]);
int y2 = Integer.valueOf((int) eventXY2[1]);
croppedBitmapByHeight = Bitmap.createBitmap(croppedBitmapByWidth, 0, 0,
croppedBitmapByWidth.getWidth(), y2);
imageView.setImageBitmap(croppedBitmapByHeight);

How to make a view like this ? Actually I tried with drawable views but can't get it

I want to make the design like image and also display same in phone and 7 inch tab.
I am using Linear layout by dividing the view in 5 part of the screen with using Framlayout draw a line but not possible to achieve like this image.
What's the other option like using canvas or any other better option.
First Image is displing expected result.
and other two are getting result.
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<gradient
android:angle="360.0"
android:endColor="#A29AA4"
android:startColor="#A29AA4" />
</shape>
Below layout
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="20dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:weightSum="5">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center">
<View
android:id="#+id/mView_circle1"
android:layout_width="20dp"
android:layout_height="20dp"
android:background="#drawable/circleshape" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center">
<View
android:id="#+id/mView_circle2"
android:layout_width="20dp"
android:layout_height="20dp"
android:background="#drawable/circleshape" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center">
<View
android:id="#+id/mView_circle3"
android:layout_width="20dp"
android:layout_height="20dp"
android:background="#drawable/circleshape" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center">
<View
android:id="#+id/mView_circle4"
android:layout_width="20dp"
android:layout_height="20dp"
android:background="#drawable/circleshape" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center">
<View
android:id="#+id/mView_circle5"
android:layout_width="20dp"
android:layout_height="20dp"
android:background="#drawable/circleshape" />
</LinearLayout>
</LinearLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_gravity="center_vertical"
android:background="#A29AA4">
</RelativeLayout>
</FrameLayout>
This is easier and cleaner in canvas. Here is how you would do the first one.. You can replicate this with slight modifications for the other two.
Create a Canvas View:
public class CanvasView extends View {
Paint bPaint;
RectF coordbounds;
public CanvasView(Context context) {
super(context);
}
private void init()
{
bPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
bPaint.setStyle(Paint.Style.FILL_AND_STROKE);
bPaint.setColor(Color.BLACK);
}
#Override
public void onDraw(android.graphics.Canvas canvas)
{
super.onDraw(canvas);
canvas.drawLine(coordbounds.left,coordbounds.centerY(),
coordbounds.right,coordbounds.centerY(),bPaint);
int circledia=20;
//Divide the line into four segments and subtract 2 * half the radii
float actualspan = (coordbounds.right - coordbounds.left) - (2 * circledia/2);
//Segment the line into 3 parts
float interlinesegments = actualspan/(4-1);
for(int i=0; i<4;i++)
{
canvas.drawCircle(coordbounds.left + circledia/2 +
(i*interlinesegments),
coordbounds.centerY(),10,bPaint);
}
}
}
Create a layout to hold the view and call this view in your activity:
LinearLayout layout = (LinearLayout) findViewById(R.id.root);
CanvasView view = new CanvasView(this);
layout.addView(view);
oops, I forgot . :-) Please add this method in CanvasView class to declare the bounding box and set the layout:
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
float xpad = (float) (getPaddingLeft() + getPaddingRight());
float ypad = (float) (getPaddingTop() + getPaddingBottom());
float coww = 0.0f, cohh = 0.0f, coll = 0.0f;
init();
coww = (float) w - xpad;
cohh = (float) h - ypad;
// Create a bounding box
coordbounds = new RectF(0.0f,0.0f,
coww,cohh);
}
EDIT : Change the above methods for bitmap
private void init()
{
bPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
bPaint.setStyle(Paint.Style.FILL_AND_STROKE);
bPaint.setColor(Color.BLACK);
bitmap = BitmapFactory.decodeResource(getResources(),
R.drawable.button);
}
Change onDraw as follows:
#Override
public void onDraw(android.graphics.Canvas canvas)
{
super.onDraw(canvas);
canvas.drawLine(coordbounds.left,coordbounds.centerY(),
coordbounds.right,coordbounds.centerY(),bPaint);
int rectwidth=bitmap.getWidth();
int rectheight=bitmap.getHeight();
//Divide the line into four segments and subtract 2 * half the radii
float actualspan = (coordbounds.right - coordbounds.left) - (2 * rectwidth/2);
//Segment the line into 3 parts
float interlinesegments = actualspan/(4-1);
for(int i=0; i<4;i++)
{
float left= coordbounds.left + (i * interlinesegments);
float top= coordbounds.centerY()-rectheight/2;
float right = coordbounds.left+(i * interlinesegments)+rectwidth;
float bottom= coordbounds.centerY()+ rectheight/2;
canvas.drawBitmap(bitmap,null,new RectF(left,top,right,bottom),null);
}
}
With the help of above code and previous code I made this Combination of circle shape and bitmap.
#Override
public void onDraw(android.graphics.Canvas canvas)
{
super.onDraw(canvas);
canvas.drawLine(coordbounds.left, coordbounds.centerY(),
coordbounds.right, coordbounds.centerY(), bPaint);
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_myprofile);
int rectwidth=bitmap.getWidth();
int rectheight=bitmap.getHeight();
//Divide the line into four segments and subtract 2 * half the radii
float actualspan_image = (coordbounds.right - coordbounds.left) - (2 * rectwidth/2);
//Segment the line into 3 parts
float interlinesegments_bitmap = actualspan_image / (4 - 1);
int circledia = 20;
//Divide the line into four segments and subtract 2 * half the radii
float actualspan = (coordbounds.right - coordbounds.left) - (2 * circledia/2);
//Segment the line into 3 parts
float interlinesegments = actualspan/(4-1);
for(int i=0; i<4;i++)
{
float left= coordbounds.left + (i * interlinesegments_bitmap);
float top= coordbounds.centerY()-rectheight/2;
float right = coordbounds.left+(i * interlinesegments_bitmap)+rectwidth;
float bottom= coordbounds.centerY()+ rectheight/2;
if(i==1){
canvas.drawBitmap(bitmap,null,new RectF(left,top,right,bottom),null);
}else{
canvas.drawCircle(coordbounds.left + circledia / 2 +
(i * interlinesegments),
coordbounds.centerY(), 10, bPaint);
}
}
}

Why image is extending bound of view out of image view in android after rotation

I have taken an image view in android. If I rotate image using onTouchListener it's view bound are extended automatically and it's coming out of layout automatically. Can any body please help me to resolve this issue.
I have attached images for more clarification.
Code for image view and rotations is given below.
XML Layout ::
<RelativeLayout
android:id="#+id/rlUserProfileLayout"
android:layout_width="fill_parent"
android:layout_height="#dimen/browseUserImageSize"
android:layout_below="#id/rlServiceNameLayout"
android:layout_marginLeft="#dimen/browseLeftRightMargin"
android:layout_marginRight="#dimen/browseLeftRightMargin"
android:layout_marginTop="#dimen/browseVIPImageTopMargin"
android:background="#drawable/user_profile_background_color">
<ImageView
android:id="#+id/imgUserProfile"
android:layout_width="fill_parent"
android:layout_height="#dimen/browseUserImageSize"
android:contentDescription="#string/app_name"
android:scaleType="matrix"
android:src="#drawable/user_image"
>
</ImageView>
<ImageView
android:id="#+id/btnLike"
android:layout_width="#dimen/browseLikeButtonHeightWidth"
android:layout_height="#dimen/browseLikeButtonHeightWidth"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:layout_marginTop="10dp"
android:layout_marginLeft="10dp"
android:src="#drawable/button_like_up_big"
android:alpha="0" />
<ImageView
android:id="#+id/btnDisLike"
android:layout_width="#dimen/browseLikeButtonHeightWidth"
android:layout_height="#dimen/browseLikeButtonHeightWidth"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_marginTop="10dp"
android:layout_marginRight="10dp"
android:src="#drawable/button_like_down_big"
android:alpha="0" />
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="#dimen/browseUserPicDetailLayoutHeight"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:background="#drawable/user_profile_detail_bottom_layout" >
<com.companyname.servicebarter.CustomTextView
android:id="#+id/txtSharedContacts"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="#dimen/browseUserPicDetailMargin"
android:text="#string/browseSharedContact"
android:textColor="#color/fc_white"
android:textSize="#dimen/browseSharedContactTextSize"
android:textStyle="bold" />
<com.companyname.servicebarter.CustomTextView
android:id="#+id/txtDistance"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="#dimen/browseUserPicDetailMargin"
android:text="#string/browseDistance"
android:textColor="#color/fc_white"
android:textSize="#dimen/browseSharedContactTextSize" />
<LinearLayout
android:id="#+id/layoutRating1"
android:layout_width="wrap_content"
android:layout_height="#dimen/browseUserPicDetailLayoutHeight"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:gravity="center_vertical"
android:orientation="horizontal" >
</LinearLayout>
</RelativeLayout>
</RelativeLayout>
Java code ::
relativeLayout.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
homeActivity.getPager().setPaging(false);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
start.set(event.getRawX(), event.getRawY());
break;
case MotionEvent.ACTION_MOVE:
v.setTranslationX(event.getRawX() - start.x);
v.setTranslationY(event.getRawY() - start.y);
x_cord = (int) ((int) event.getRawX() - start.x);
y_cord = (int) ((int) event.getRawY() - start.y);
v.setRotation((float) ((x_cord) * (Math.PI / 32)));
if (x_cord >= 0) {
if (x_cord > (screenCenter / 2)) {
// imageLike.setAlpha(1);
/*
* SET ALPHA BY MATYHEMATIC RULE Y=MX+C THIS FORMULA
* GIVE US LINEAR VALUE
*/
btnLike.setAlpha((float) (event.getRawX() / (2 * (screenCenter))));
// btnLike.setVisibility(View.VISIBLE);
Log.d("ads",
""
+ (float) (event.getRawX() / (0.5 * (screenCenter))));
if (x_cord > (screenCenter / 4)) {
Likes = 2;
} else {
Likes = 0;
}
} else {
Likes = 0;
btnLike.setAlpha(0.0f);
}
btnDisLike.setAlpha(0.0f);
} else {
// rotate
if (Math.abs(x_cord) > (screenCenter / 2)) {
btnDisLike.setAlpha(1 - (float) (event.getRawX() / (0.5 * screenCenter)));
if (x_cord < screenCenter / 4) {
Likes = 1;
} else {
Likes = 0;
}
} else {
Likes = 0;
btnDisLike.setAlpha(0.0f);
}
// imageLike.setAlpha(0);
// btnLike.setVisibility(View.GONE);
btnLike.setAlpha(0.0f);
}
break;
case MotionEvent.ACTION_UP:
btnLike.setAlpha(0.0f);
btnDisLike.setAlpha(0.0f);
homeActivity.getPager().setPaging(true);
if (Likes == 0) {
v.animate().translationX(_xDelta);
v.animate().translationY(_yDelta);
v.setRotation(0.0f);
} else if (Likes == 1) {
v.animate().translationX(_xDelta);
v.animate().translationY(_yDelta);
v.setRotation(0.0f);
buttonDisLikeClicked();
} else if (Likes == 2) {
v.animate().translationX(_xDelta);
v.animate().translationY(_yDelta);
v.setRotation(0.0f);
buttonLikeClicked();
}
break;
}
return true;
}
});
Can any body please suggest me why I am facing this issue? Thanks in advance.

Circular Layout

I want to develop following screen in Android.
I used CircleLayout but I am still not able to achieve desired output. See following code and screenshot.
<com.example.hl.CircleLayout
android:id="#+id/pie"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/white"
custom:dividerWidth="5dp"
custom:innerCircle="#drawable/profile_pic_icon"
custom:innerRadius="50dp"
custom:layoutMode="pie"
custom:sliceDivider="#android:color/transparent" >
<RelativeLayout
android:id="#+id/appt_center_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/appt_center_bg" >
<TextView
android:id="#+id/one"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:onClick="onClick"
android:text="APP CENTER"
android:textStyle="bold" />
</RelativeLayout>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/meds_cabinet_bg" >
<TextView
android:id="#+id/two"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:onClick="onClick"
android:text="MEDS CABINET"
android:textStyle="bold" />
</RelativeLayout>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/check_in_bg" >
<TextView
android:id="#+id/three"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:onClick="onClick"
android:text="CHECK-IN"
android:textStyle="bold" />
</RelativeLayout>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/my_tracker_bg" >
<TextView
android:id="#+id/four"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:onClick="onClick"
android:text="MY TRACKERS"
android:textStyle="bold" />
</RelativeLayout>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/myaccount_bg" >
<TextView
android:id="#+id/five"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:onClick="onClick"
android:text="MY ACCOUNTS"
android:textStyle="bold" />
</RelativeLayout>
</com.example.hl.CircleLayout>
screenshot
Question:-
Is there any other library that can help developing the desired screen?
How to develop such screen using custom view? I mean what are steps to develop such custom view easily?
I have implemented a library for circular layout. Currently under development, basically meets need I think. Feel free to fork and develop.
https://github.com/ycagri/CircularLayout
End of Edit
You can use a custom layout given below. Number of items, inner radius and outer radius are defined in class. You can use those variables as custom layout attribute. The layout given below draws android launcher icon in the middle and around the circles. Titles are drawn below selection items.
Screenshot belongs to Nexus 7 device. Extra margin and padding can be defined to get better results on different screen resolutions.
public class CircleLayout extends View {
private final static int TOTAL_DEGREE = 360;
private final static int START_DEGREE = -90;
private Paint mPaint;
private RectF mOvalRect = null;
private int mItemCount = 5;
private int mSweepAngle;
private int mInnerRadius;
private int mOuterRadius;
private Bitmap mCenterIcon;
private int[] mColors = {Color.RED, Color.YELLOW, Color.GREEN, Color.BLUE, Color.CYAN};
private String[] mTitles = {"APPT CENTER", "MEDS CABINET", "CHECK-IN", "MY TRACKERS", "MY ACCOUNTS"};
public CircleLayout(Context context) {
this(context, null);
}
public CircleLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CircleLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setStrokeWidth(2);
mSweepAngle = TOTAL_DEGREE / mItemCount;
mInnerRadius = 125;
mOuterRadius = 400;
mCenterIcon = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
}
#Override
protected void onDraw(Canvas canvas) {
int width = getWidth();
int height = getHeight();
if (mOvalRect == null) {
mOvalRect = new RectF(width / 2 - mOuterRadius, height / 2 - mOuterRadius, width / 2 + mOuterRadius, height / 2 + mOuterRadius);
}
for (int i = 0; i < mItemCount; i++) {
int startAngle = START_DEGREE + i * mSweepAngle;
mPaint.setColor(mColors[i]);
mPaint.setStyle(Paint.Style.FILL);
canvas.drawArc(mOvalRect, startAngle, mSweepAngle, true, mPaint);
mPaint.setColor(Color.BLACK);
mPaint.setStyle(Paint.Style.STROKE);
canvas.drawArc(mOvalRect, startAngle, mSweepAngle, true, mPaint);
int centerX = (int) ((mOuterRadius + mInnerRadius) / 2 * Math.cos(Math.toRadians(startAngle + mSweepAngle / 2)));
int centerY = (int) ((mOuterRadius + mInnerRadius) / 2 * Math.sin(Math.toRadians(startAngle + mSweepAngle / 2)));
canvas.drawBitmap(mCenterIcon, width / 2 + centerX - mCenterIcon.getWidth() / 2, height / 2 + centerY - mCenterIcon.getHeight() / 2, null);
mPaint.setColor(Color.BLACK);
mPaint.setStyle(Paint.Style.FILL);
canvas.drawText(mTitles[i], width / 2 + centerX - mCenterIcon.getWidth() / 2, height / 2 + centerY + mCenterIcon.getHeight(), mPaint);
}
mPaint.setColor(Color.WHITE);
mPaint.setStyle(Paint.Style.FILL);
canvas.drawCircle(width / 2, height / 2, mInnerRadius, mPaint);
canvas.drawBitmap(mCenterIcon, width / 2 - mCenterIcon.getWidth() / 2, height / 2 - mCenterIcon.getHeight() / 2, null);
super.onDraw(canvas);
}
}

android RadioButton button drawable gravity

I am generating RadioButtons dynamically with
RadioButton radioButton=new RadioButton(context);
LayoutParams layoutParams=new LayoutParams(radioWidth,radioHeight);
layoutParams.gravity=Gravity.CENTER;
radioButton.setLayoutParams(layoutParams);
radioButton.setGravity(Gravity.CENTER);
BitmapDrawable bitmap = ((BitmapDrawable)drawableResource);
bitmap.setGravity(Gravity.CENTER);
radioButton.setBackgroundDrawable(getResources().getDrawable(R.drawable.itabs_radio));
radioButton.setButtonDrawable(bitmap);
as you can see I am desperately trying to set gravity of button drawable to center, but without a reason its always center and left aligned, heres the reason- the default style of android radio button:
<style name="Widget.CompoundButton">
<item name="android:focusable">true</item>
<item name="android:clickable">true</item>
<item name="android:textAppearance">?android:attr/textAppearance</item>
<item name="android:textColor">?android:attr/textColorPrimaryDisableOnly</item>
<item name="android:gravity">center_vertical|left</item>
</style>
<style name="Widget.CompoundButton.RadioButton">
<item name="android:background">#android:drawable/btn_radio_label_background</item>
<item name="android:button">#android:drawable/btn_radio</item>
</style>
Is there any way I can align button drawable to center?
According to CompoundButton.onDraw() source code it's always left-aligned.
(Note the line buttonDrawable.setBounds(0, y, buttonDrawable.getIntrinsicWidth(), y + height);)
You will have to derive a new class from RadioButton and override onDraw().
EXAMPLE ADDED LATER:
Ok, so here's what you do. Firstly, here's a layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<org.test.TestProj.RadioButtonCenter
android:id="#+id/myview"
android:layout_width="fill_parent"
android:layout_height="100dp"
android:layout_centerInParent="true"
android:text="Button test"
/>
</RelativeLayout>
Secondly here's the custom-drawing RadioButtonCenter:
package org.test.TestProj;
import android.content.Context;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.Gravity;
import android.widget.RadioButton;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
public class RadioButtonCenter extends RadioButton {
public RadioButtonCenter(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CompoundButton, 0, 0);
buttonDrawable = a.getDrawable(1);
setButtonDrawable(android.R.color.transparent);
}
Drawable buttonDrawable;
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (buttonDrawable != null) {
buttonDrawable.setState(getDrawableState());
final int verticalGravity = getGravity() & Gravity.VERTICAL_GRAVITY_MASK;
final int height = buttonDrawable.getIntrinsicHeight();
int y = 0;
switch (verticalGravity) {
case Gravity.BOTTOM:
y = getHeight() - height;
break;
case Gravity.CENTER_VERTICAL:
y = (getHeight() - height) / 2;
break;
}
int buttonWidth = buttonDrawable.getIntrinsicWidth();
int buttonLeft = (getWidth() - buttonWidth) / 2;
buttonDrawable.setBounds(buttonLeft, y, buttonLeft+buttonWidth, y + height);
buttonDrawable.draw(canvas);
}
}
}
Finally, here's an attrs.xml file you need to put in res/values so the code can get at platform-defined attributes.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="CompoundButton">
<attr name="android:button" />
</declare-styleable>
</resources>
Simple solution, you can add a background to RadioButton, or set background="#null", .
<RadioButton
android:id="#+id/cp_rd_btn"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#null"/>
updated:
<RadioGroup
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<RadioButton
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#null"
android:button="#null"
android:drawableTop="#drawable/account_coolme_selector"
android:gravity="center" />
<RadioButton
android:layout_width="0dp"
android:layout_height="fill_parent"
android:layout_weight="1"
android:background="#null"
android:button="#null"
android:drawableTop="#drawable/account_qq_selector"
android:gravity="center"
/>
</RadioGroup>
Based on #hoot answers, I had customised it to make both text and drawable to the center without using attars,
class RadioButtonCenter(context: Context, attrs: AttributeSet) : RadioButton(context, attrs) {
internal var buttonDrawable: Drawable? = null
init {
buttonDrawable = CompoundButtonCompat.getButtonDrawable(this#RadioButtonCenter)
}
override fun onDraw(canvas: Canvas) {
val iconHeight = buttonDrawable!!.intrinsicHeight
val buttonWidth = buttonDrawable!!.intrinsicWidth
val totalWidth =
buttonWidth + paint.measureText(text.toString()) + paddingLeft + paddingRight + compoundDrawablePadding
if (totalWidth >= width) {
super.onDraw(canvas)
} else {
setButtonDrawable(android.R.color.transparent)
val availableSpace = ((width - totalWidth) / 2).toInt()
buttonDrawable!!.state = drawableState
val height = height
var yTop = 0
val verticalGravity = gravity and Gravity.VERTICAL_GRAVITY_MASK
when (verticalGravity) {
Gravity.BOTTOM -> yTop = height - iconHeight
Gravity.CENTER_VERTICAL -> yTop = (height - iconHeight) / 2
}
var rightWidth = availableSpace + buttonWidth
buttonDrawable!!.setBounds(availableSpace, yTop, rightWidth, yTop + iconHeight)
buttonDrawable!!.draw(canvas)
rightWidth += compoundDrawablePadding
val yPos = (height / 2 - (paint.descent() + paint.ascent()) / 2) as Float
canvas.drawText(
text.toString(),
(rightWidth).toFloat(),
yPos,
paint
)
}
}
}
Based on #Reprator answers.
JAVA version:
public class RadioButtonCentered extends AppCompatRadioButton {
private Drawable buttonDrawable;
public RadioButtonCentered(Context context) {
super(context);
}
public RadioButtonCentered(Context context, AttributeSet attrs) {
super(context, attrs);
}
public RadioButtonCentered(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#Override
protected void onDraw(Canvas canvas) {
if (buttonDrawable != null) {
int iconHeight = buttonDrawable.getIntrinsicHeight();
int buttonWidth = buttonDrawable.getIntrinsicWidth();
int width = getWidth();
float totalWidth = buttonWidth + getPaint().measureText(getText().toString()) + getPaddingLeft() + getPaddingRight() + getCompoundDrawablePadding();
if (totalWidth >= width) { super.onDraw(canvas); }
else {
int yTop = 0;
int height = getHeight();
int availableSpace = (int) ((width - totalWidth) / 2);
int verticalGravity = getGravity() & Gravity.VERTICAL_GRAVITY_MASK;
int rightWidth = availableSpace + buttonWidth;
switch (verticalGravity) {
case Gravity.BOTTOM:
yTop = height - iconHeight;
break;
case Gravity.CENTER_VERTICAL:
yTop = (height - iconHeight) / 2;
break;
}
setButtonDrawable(android.R.color.transparent);
buttonDrawable.setState(getDrawableState());
buttonDrawable.setBounds(availableSpace, yTop, rightWidth, yTop + iconHeight);
buttonDrawable.draw(canvas);
float yPos = (height / 2 - (getPaint().descent() + getPaint().ascent()) / 2);
canvas.drawText(getText().toString(), ((float) (rightWidth + getCompoundDrawablePadding())), yPos, getPaint());
}
} else {buttonDrawable = CompoundButtonCompat.getButtonDrawable(this); invalidate();}
}
}
I also think this sounds like a bug since it's always left-aligned. In my case I solved the issue by setting android:minWidth="0dp" and android:layout_width="wrap_content", since Material components had set the android:minWidth to a width larger than the drawable width. If the RadioButton needs to be centered it can then be added to a container and thus no custom view needs to be implemented.
Here's an example of how it could look:
<FrameLayout
android:layout_width="200dp"
android:layout_height="200dp">
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:clickable="false"
android:minWidth="0dp" />
</FrameLayout>
However, be aware that the minimum width was set there for a reason, Material design used ?attr/minTouchTargetSize. So if you do like above, the container should maybe also be touchable.
<radiogroup android:paddingLeft = "20dp" android:background="#color/gray">
Basically - I have a horizontally aligned radio group, and by expanding the background color to the left 20dp (or whatever 1/2 of your width of radio button) it appears as if it's centered.
you need foreground. not background. see args for layout and set em programmatically:
<RadioButton>
...
android:button="#null"
android:foreground="#drawable/your_selector_for_center_drawable"
android:background="#drawable/your_selector_for_background_drawable"
android:foregroundGravity="center"
</RadioButton>

Categories

Resources