Android: ListView, problem with rounded corners - android

I have ListView with rounded corners implemented like bellow.
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#drawable/list_bg"
android:divider="#dbdbdb"
android:dividerHeight="1sp"
android:cacheColorHint="#00000000"
android:descendantFocusability="afterDescendants"
android:scrollbars="vertical">
</ListView>
where list_bg.xml is:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#ffffff"/>
<corners android:bottomLeftRadius="10dp"
android:bottomRightRadius="10dp"
android:topLeftRadius="10dp"
android:topRightRadius="10dp"
/>
</shape>
This give me rounded corners.
The problem is that each items are RelativeLayout with TextView on the left side and ImageButton on the right side. Both views have custom graphic on pressed, foucused and default state. Something like this.
+------------------------------------+
| TextView | ImageButton |
+------------------------------------+
The problem is that custom graphic cover ListView background and thus rounded corners on first and last item. Everything is okay when scrolling.
I've written custom adapter and in getView method I set proper bg for items.
#Override
public View getView(int position, View view, ViewGroup parent) {
...
if(position == 0) {
mItemView.setBackgroundResource(R.drawable.cell_item_first_selector);
mImgBtn.setBackgroundResource(R.drawable.cell_btn_first_selector);
}
else if (position == mData.size() -1) {
mItemView.setBackgroundResource(R.drawable.cell_item_last_selector);
mImgBtn.setBackgroundResource(R.drawable.cell_btn_last_selector);
}
else {
mItemView.setBackgroundResource(R.drawable.cell_item_def_selector);
mImgBtn.setBackgroundResource(R.drawable.cell_btn_def_selector);
}
...
}
It works, but I'm not sure that is good solution. Is there any other way to automatically round corners in Android Views, not just by setting background?

public class ClippedListView extends ListView {
/**
* #param context
*/
public ClippedListView(Context context) {
super(context);
}
/**
* #param context
* #param attrs
*/
public ClippedListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
protected void dispatchDraw(Canvas canvas) {
float radius = 10.0f;
Path clipPath = new Path();
RectF rect = new RectF(0, 0, this.getWidth(), this.getHeight());
clipPath.addRoundRect(rect, radius, radius, Path.Direction.CW);
canvas.clipPath(clipPath);
super.dispatchDraw(canvas);
}
}
First clipping was not working, then using
setLayerType(View.LAYER_TYPE_SOFTWARE, null)
on my clippedListView solve the issue. My items' background are not messing with my corners anymore!

Well, if you need this background for the items in the list, you should attach the background to the item layout, and not to the list view.

Related

Change RecyclerView.ItemDecoration color per item

I'm using a custom item decorator for my recyclerview and it works fine.
MyItemDecorationTest.java
public class MyItemDecorationTest extends RecyclerView.ItemDecoration{
private Paint paint;
private final static int OFFSET = 8;
public MyItemDecorationTest(Paint paint){
this.paint = paint;
}
#Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
outRect.set(OFFSET, OFFSET, OFFSET, OFFSET);
}
#Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
super.onDraw(c, parent, state);
final RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
for(int i=0; i<parent.getChildCount(); i++){
final View child = parent.getChildAt(i);
c.drawRoundRect(layoutManager.getDecoratedLeft(child) + OFFSET,
layoutManager.getDecoratedTop(child) + OFFSET,
layoutManager.getDecoratedRight(child) - OFFSET,
layoutManager.getDecoratedBottom(child) - OFFSET, 2, 2, paint);
}
}
}
And this is how I include it in my activity:
RecyclerView.ItemDecoration itemDecoration = new MyItemDecorationTest(getPaint(getResources().getColor(R.color.block_blue)));
recyclerView.addItemDecoration(itemDecoration);
And this is my method to set the paint.
public Paint getPaint(int color){
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(color);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(4);
return paint;
}
This is the render:
Now I want to change the color of the decorator per item. That means for instance change the blue color of the second item with red. And this is what I expect to have:
Is there any way to change decoration color on a per item basis using RecyclerView.ItemDecoration?
Instead of using ItemDecoration for changing the color of your items, you should consider drawing the borders directly in the layout and change the color of the layout at runtime.
You can do for instance:
corner.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<stroke
android:width="2dp"
android:color="#07AFF2" />
<solid android:color="#ffffff" />
<padding
android:left="1dp"
android:right="1dp"
android:top="1dp" />
<corners android:radius="3dp" />
</shape>
Add it into your drawable folder. your layout.xml file should look like:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/bloc"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/corner">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="#+id/textView"
android:textColor="#color/colorBlack"
android:gravity="center_vertical"
android:layout_gravity="center_vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Element" />
</LinearLayout>
</LinearLayout>
My solution is:
override getItemViewType(int position) to return different view types,
provide different layouts for different view types,
override onCreateViewHolder(#NonNull ViewGroup parent, int viewType) to inflate different layouts,
provide drawables in different colors,
pass all the drawables to your ItemDecoration in its constructor,
override onDraw(Canvas canvas, RecyclerView parent, RecyclerView.State state) to select correct drawable for each view type.
My example with different colors
I also tried changing color programmatically but it looks like it does not work...
From your RecyclerView Adapter's 'onBindViewHolder' method, you can pass the current item position to your Viewholder and update the item to the desired color from there.

Imageview to fit layout with border and rounded corners

I was wondering if you could help me with something. I have a relative layout with an imageview at the top. Around the relative layout I have a border (layout_bg.xml). As you can see from the image I attached, the border doesn't continue around the image, which is what I want it to do. I know I need some extra code here but as I am quite new to java I haven't been able to figure it out or find a solution online, and I was hoping you could help me or point me in the right direction.
What I want to do:
Have the image fit my frame but with border and rounded top left and right corners.
image
layout_bg.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#FFFFFF"/>
<corners android:radius="8dp"/>
<stroke android:width="3dp" android:color="#50A4A4A4" />
<padding android:left="0dp" android:top="0dp" android:right="0dp" android:bottom="0dp" />
</shape>
item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:geekui="http://schemas.android.com/apk/res-auto"
android:background="#drawable/layout_bg"
android:layout_gravity="center"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="30dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginBottom="70dp">
<ImageView
android:id="#+id/imageView_player"
android:adjustViewBounds="true"
android:scaleType="fitXY"
android:layout_width="match_parent"
android:layout_height="225dp"
android:layout_alignParentTop="true" />
</RelativeLayout>
Check out code below, which make an ImageView have round corners on top-left and top-right.
public class TopRoundImageView extends ImageView {
public TopRoundImageView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public TopRoundImageView(Context context) {
super(context);
init();
}
private final RectF roundRect = new RectF();
private float rect_adius = 7;
private final Paint maskPaint = new Paint();
private final Paint zonePaint = new Paint();
private void init() {
maskPaint.setAntiAlias(true);
maskPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
zonePaint.setAntiAlias(true);
zonePaint.setColor(Color.WHITE);
float density = getResources().getDisplayMetrics().density;
rect_adius = rect_adius * density;
}
public void setRectAdius(float adius) {
rect_adius = adius;
invalidate();
}
#Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
int w = getWidth();
int h = getHeight();
roundRect.set(0, 0, w, h + rect_adius);
}
#Override
public void draw(Canvas canvas) {
canvas.saveLayer(roundRect, zonePaint, Canvas.ALL_SAVE_FLAG);
canvas.drawRoundRect(roundRect, rect_adius, rect_adius, zonePaint);
canvas.saveLayer(roundRect, maskPaint, Canvas.ALL_SAVE_FLAG);
super.draw(canvas);
canvas.restore();
}
You could use the RoundedBitmapDrawableFactory RoundedBitmapDrawable classes like this
RoundedBitmapDrawable roundedDrawable = RoundedBitmapDrawableFactory.create(getResources(), BitmapFactory.decodeResource(getResources(), R.drawable.your_drawable_resource));
To set the corner radius, do this
roundedDrawable.setCornerRadius(5.0f);
and then set it on your ImageView like this
imageView.setDrawableResource(roundedDrawable)
Click HERE
to learn more about the RoundedBitmapDrawableFactory class.
and HERE
for the RoundedBitmapDrawable class
Hope this helps.

Drawing on top of an image to create an animation

I'm new on Android, and I am having trouble with the following:
I have an image of an empty test-tube (png or bmp).
And I need to draw lines on top of it to make the illusion that its being filled in with liquid.
I really don't know how to proceed. I have read google's documentation about animations, but that didn't help much.
I'd appreciate if you guys could give me some suggestions of how it can be done, and point to some tutorials/documentation that can help me.
Thanks in advance.
UPDATE:
The tube is not retangular, the bottom is oval.
I think I need to make the liquid fall into the test tube, then paint line by line, starting from the bottom. And I have to check for the borders of the tube (right and lef black pixels).
Any ideas of how this can be done?
UPDATE 2:
Here is the tube image: http://i61.tinypic.com/2nw0eb9.png
You can use a SurfaceView to draw what ever you want:
Basicly, you lock the surface's canvas by
Canvas canvas = mSurfaceView.getHolder().lockCanvas();
Then, use the canvas's methods to draw on it. canvas.drawBitmap, canvas.drawLine etc..
When you're finished lock the canvas with mSurfaceView.getHolder().unlockCanvasAndPost(canvas); and you're done.
here's an example from a quick google search:
http://android-coding.blogspot.co.il/2011/05/drawing-on-surfaceview.html
Best way to do this would be with a custom View. Make a new class, that extends View, then in its onDraw method first draw the picture, then draw your animations. If you want to do it by hand, you can do something like this:
private class TestTubeView extends View {
private int top = 0;
private Paint myPaint;
public MyView(Context context) {
super(context);
myPaint = new Paint();
myPaint.setColor(getResources().getColor(R.color.blue));
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//First draw your bitmap
canvas.drawBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.my_testtube), 0, 0, myPaint); //might need to use a different paint
//Then your "animation" as a static image, that has its position set from a variable, in this case "y" and "x"
canvas.drawRect(0, top, getWidth(), getHeight(), myPaint);
}
//In this method update your variables, that define the positions of your animated lines / bubbles
public boolean updateAnimation() {
top++;
invalidate();
//So it stops animationg
return top > getHeight();
}
}
Then in your layout you put it in like a normal view:
<com.example.TestTubeView
android:id="#+id/my_testtube"
android:layout_width="20dp"
android:layout_height="200dp" />
And then you animate it with a self-repeating Runnable:
final MyView testTube = findViewById(R.id.my_testtube);
final Handler myHandler = new Handler();
myHandler.post(new Runnable() {
#Override
public void run() {
if(testTube.updateAnimation()){
myHandler.postDelayed(this, 200);
}
}
});
You'll have to play around with sizes / heights and things like that though. Another way of doing this is with an ObjectAnimatior
Tube Drawable: (this is for test purposes. you will use your tube image)
tube.xml (drawable folder)
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<stroke android:width="5dp" android:color="#ffccffff" />
<solid android:color="#00000000" />
</shape>
tube_activity.xml
<?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:gravity="center" >
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<LinearLayout
android:id="#+id/orangeJuiceLinearLayout"
android:layout_width="140dp"
android:layout_height="0dp"
android:layout_gravity="bottom"
android:orientation="vertical"
android:background="#fff58225">
</LinearLayout>
<ImageView
android:id="#+id/tubeImageView"
android:layout_width="140dp"
android:layout_height="220dp"
android:layout_gravity="center"
android:background="#drawable/tube"
android:onClick="fillJuice"
android:clickable="true" />
</FrameLayout>
</LinearLayout>
TubeAcivity.java
public class TubeActivity extends Activity {
LinearLayout orangeLL;
ImageView tubeIV;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.tube_activity);
orangeLL = (LinearLayout)findViewById(R.id.orangeJuiceLinearLayout);
tubeIV = (ImageView)findViewById(R.id.tubeImageView);
}
public void fillJuice(View view) {
ValueAnimator va = ValueAnimator.ofInt(0, tubeIV.getMeasuredHeight());
va.setDuration(1500);
va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
public void onAnimationUpdate(ValueAnimator animation) {
Integer value = (Integer) animation.getAnimatedValue();
orangeLL.getLayoutParams().height = value.intValue();
orangeLL.requestLayout();
}
});
va.start();
}
}

Android Text should appear both side in the Switch

I using custom switch for support of API 8. I am using THIS Libarary for Custom Switch. But I want to make something Like show in figure.I have tried to change the color ,though changing the color in the style but doesn't effect as i want.
Please help me , Thanks in advance.
Here's a full, working solution, after a fun day implementing this.
Use the following to set the drawable for the track of the switch. The track is the container within which the thumb slides left and right.
mMessengerSwitch.setTrackDrawable(new SwitchTrackTextDrawable(this,
"LEFT", "RIGHT"));
Here's the implementation of the SwitchTrackTextDrawable, which writes the text in the background exactly in the right position (well, I've only tested it for API 23 on a Nexus 5):
/**
* Drawable that generates the two pieces of text in the track of the switch, one of each
* side of the positions of the thumb.
*/
public class SwitchTrackTextDrawable extends Drawable {
private final Context mContext;
private final String mLeftText;
private final String mRightText;
private final Paint mTextPaint;
public SwitchTrackTextDrawable(#NonNull Context context,
#StringRes int leftTextId,
#StringRes int rightTextId) {
mContext = context;
// Left text
mLeftText = context.getString(leftTextId);
mTextPaint = createTextPaint();
// Right text
mRightText = context.getString(rightTextId);
}
private Paint createTextPaint() {
Paint textPaint = new Paint();
//noinspection deprecation
textPaint.setColor(mContext.getResources().getColor(android.R.color.white));
textPaint.setAntiAlias(true);
textPaint.setStyle(Paint.Style.FILL);
textPaint.setTextAlign(Paint.Align.CENTER);
// Set textSize, typeface, etc, as you wish
return textPaint;
}
#Override
public void draw(Canvas canvas) {
final Rect textBounds = new Rect();
mTextPaint.getTextBounds(mRightText, 0, mRightText.length(), textBounds);
// The baseline for the text: centered, including the height of the text itself
final int heightBaseline = canvas.getClipBounds().height() / 2 + textBounds.height() / 2;
// This is one quarter of the full width, to measure the centers of the texts
final int widthQuarter = canvas.getClipBounds().width() / 4;
canvas.drawText(mLeftText, 0, mLeftText.length(),
widthQuarter, heightBaseline,
mTextPaint);
canvas.drawText(mRightText, 0, mRightText.length(),
widthQuarter * 3, heightBaseline,
mTextPaint);
}
#Override
public void setAlpha(int alpha) {
}
#Override
public void setColorFilter(ColorFilter cf) {
}
#Override
public int getOpacity() {
return PixelFormat.TRANSLUCENT;
}
}
Try using
android:textOn="On"
android:textOff="Off"
instead of
android:text="On"
in switches.
You can also go through this if it helps.
After struggling to find the right solution for this, I found this neat little library. I found it easy to use and it met my needs perfectly. It can even be used to display more than 2 values.
UPDATE: In the meanwhile this library has stopped being maintained, so you may want to try the one they recommend.
This is how I made it look eventually with some more styling, like white border which I put around a FrameLayout that wraps it (I needed to make it look exactly like this, you need not use border):
Here's the xml for this:
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="1dp"
android:background="#drawable/white_border">
<belka.us.androidtoggleswitch.widgets.ToggleSwitch
android:layout_width="wrap_content"
android:layout_height="wrap_content"
custom:activeBgColor="#color/white"
custom:activeTextColor="#color/black"
custom:inactiveBgColor="#color/black"
custom:inactiveTextColor="#color/white"
custom:textToggleLeft="left"
custom:textToggleRight="right"/>
</FrameLayout>
And #drawable/white_border looks like this:
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
<solid android:color="#android:color/transparent" />
<stroke android:width="2dip"
android:color="#color/white" />
<corners
android:radius="3dp"/>
I created a custom layout that contain a linear layout (will be used as a track of the switch) in this layout I placed two texts to simulate the track "on"/"off" texts, and on top of it, it has a regular switch but without a track, just a thumb with transparent track.
Anyway this is the code:
colors.xml
<color name="switch_selected_text_color">#FFFFFF</color>
<color name="switch_regular_text_color">#A8A8A8</color>
settings_switch_color_selector
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="#color/switch_selected_text_color" android:state_checked="true" />
<item android:color="#color/switch_regular_text_color" />
</selector>
styles.xml
<style name="SwitchTextAppearance" parent="#android:style/TextAppearance.Holo.Small">
<item name="android:textColor">#color/settings_switch_color_selector</item>
</style>
new_switch.xml - used in the custom view
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<LinearLayout
android:id="#+id/track_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/settings_track"
android:weightSum="1">
<TextView
android:id="#+id/left_text"
android:layout_width="0dp"
android:layout_height="match_parent"
android:textColor="#color/switch_regular_text_color"
android:layout_weight="0.5"
android:gravity="center"
android:text="OFF" />
<TextView
android:id="#+id/right_text"
android:layout_width="0dp"
android:layout_height="match_parent"
android:textColor="#color/switch_regular_text_color"
android:layout_weight="0.5"
android:gravity="center"
android:text="ON" />
</LinearLayout>
<Switch
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:thumb="#drawable/thumb_selector"
android:switchTextAppearance="#style/SwitchTextAppearance"
android:textOn="ON"
android:textOff="OFF"
android:checked="true"
android:showText="true"
android:track="#android:color/transparent"/>
</RelativeLayout>
this is custom view - it`s just for inflating the custom view layout
public class DoubleSidedSwitch extends RelativeLayout {
private TextView _leftTextView;
private TextView _rightTextView;
private Switch _switch;
public DoubleSidedSwitch(Context context) {
super(context);
init(context);
}
public DoubleSidedSwitch(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
private void init(Context context) {
View view = LayoutInflater.from(context).inflate(R.layout.new_switch, this, true);
initViews(view);
initListeners();
}
private void initListeners() {
}
private void initViews(View view) {
}
}
There is one made by 2 Standard buttons and a LinearLayout. There are bunch of xml files to import but it works perfect on all versions and very easy to use. Check the following Github Page
Custom Switch With 2 Buttons
usage
Copy XML files under res/drawable to your project's res/drawable folder.
Copy LinearLayout from layout.xml to your layout file.
Copy values from values/colors.xml and values/dimens to your own files.
Initilize the switch with following code
SekizbitSwitch mySwitch = new SekizbitSwitch(findViewById(R.id.sekizbit_switch));
mySwitch.setOnChangeListener(new SekizbitSwitch.OnSelectedChangeListener() {
#Override
public void OnSelectedChange(SekizbitSwitch sender) {
if(sender.getCheckedIndex() ==0 )
{
System.out.println("Left Button Selected");
}
else if(sender.getCheckedIndex() ==1 )
{
System.out.println("Right Button Selected");
}
}
});

Set gradient radius at runtime and center it around a button

Like many other posts listed here i struggle with radial gradient.
post 1, 2, 3...
I want 2 things:
set a gradient around a button that has a selector as background drawable to get an aura effect
adjust this gradient radius to have the same feel independently of the screen resolution/size.
What I have done so far: Solution 1
I tried to implement several solutions found around. I show here my 2 best tries. I set a drawable with a gradient to the background of an enclosing layout around my button. That fulfills the point 1)
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/custom_background"
android:gravity="center"
android:padding="#dimen/padding_extra_large" >
<Button
android:id="#+id/snap_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/custom_button" />
</FrameLayout>
This is my #drawable/custom_background
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item>
<!-- Circular gradient -->
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<gradient
android:endColor="#ffdbdbdb"
android:gradientRadius="180"
android:startColor="#ff000000"
android:type="radial"
android:innerRadiusRatio="2"
/>
</shape>
</item>
What I have done so far: Solution 2
The effect is good but android:gradientRadius="180" has to be adjust for each screen. Post 1 provided some solution and I tried to customize a layout and a view but I got crashes. Some configuration did not fail (with background set to root layout but in this case onDraw was never called).
Customized view :
public class GradientView extends View {
Paint paint;
RadialGradient gradient;
int maxSize;
public GradientView(Context context) {
super(context);
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
this.setWillNotDraw(false);
// TODO Auto-generated constructor stub
}
#Override
protected void onDraw(Canvas canvas) {
Dbg.e("RelativeLayoutSnapBook", " - onDraw !!!");
maxSize = Math.max(getHeight(), getWidth());
RadialGradient gradient = new RadialGradient(
getWidth()/2,
getHeight()/2,
maxSize,
new int[] {Color.RED, Color.BLACK},
new float[] {0, 1},
android.graphics.Shader.TileMode.CLAMP);
paint.setDither(true);
paint.setShader(gradient);
canvas.drawRect(0, 0, getWidth(), getHeight(), paint);
}
}
and this view goes here :
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:padding="#dimen/padding_extra_large" >
<com.snapcar.rider.widget.GradientView
android:layout_width="match_parent"
android:layout_height="match_parent" />
<Button
android:id="#+id/snap_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#drawable/snap_button" />
</FrameLayout>
These is the fail : error when inflating the fragment with stack and stack of intern error :
10-29 18:55:25.794: E/AndroidRuntime(11828): FATAL EXCEPTION: main
10-29 18:55:25.794: E/AndroidRuntime(11828): android.view.InflateException: Binary XML file line #33: Error inflating class com.xxx.widget.GradientView
10-29 18:55:25.794: E/AndroidRuntime(11828): Caused by: java.lang.ClassNotFoundException: com.xxx.rider.widget.GradientView in loader dalvik.system.PathClassLoader[/system/framework/com.google.android.maps.jar:/data/app/com.snapcar.rider-1.apk]
Can you help me to do that please ? Thanks a lot!
Edit : someone?
I solved it ! So much trouble :/ If you know Photoshop, you better go with it I think!
Thanks to this post that gave me the way to go : multiple-gradrient Only the first code extract was used but the whole post might interested you if you reached this post.
So I entirely define my gradient with code using a callback on global layout:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Log.v(TAG, "- onCreateView Fragment");
root = inflater.inflate(R.layout.fragment_layout, null);
root.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
Log.e(TAG, "- On Layout Completed ! ");
final FrameLayout frame = (FrameLayout) root.findViewById(R.id.frame_layout_gradient);
ShapeDrawable.ShaderFactory sf = new ShapeDrawable.ShaderFactory() {
#Override
public Shader resize(int width, int height) {
Log.e(TAG, " - onGlobalLayout : getWidth = "+ frame.getWidth() +" - getHeight = "+ frame.getHeight() );
RadialGradient lg = new RadialGradient(frame.getWidth()/2, frame.getHeight()/2,
frame.getWidth()/2, Color.BLACK, Color.parseColor("#FFdbdbdb"), TileMode.CLAMP);
return lg;
}
};
PaintDrawable p = new PaintDrawable();
p.setShape(new OvalShape());
p.setShaderFactory(sf);
frame.setBackgroundDrawable((Drawable)p);
}
}
);
This trick Color.parseColor("#FFdbdbdb") is need because the retard constructor of RadialGradient cannot read correctly the reference to your R.color.the_gray_I_want
The OvalShape does a circle in my case because my frameLayout is square.
With this solution, you have a shadowing totally independent of screen characteristics.
![the result - unvarying from SG3 to HTC wildfire!1

Categories

Resources