I want to develop Rating bar like zomato android application. In which the rating bar box changes it's color according to selection. if only one box is selected then it's color is Read and gradually we select more box it became Green.
Here I attached snap of zomato android app's screen portion which shows Rating exactly I would like to develop this type of Rating and Review System.
That's a simple horizontal LinearLayout with 9 TextViews, each of them having grey as the default color. Aditionally you can create an array of strings, each string being a color code. This is the quick and dirty solution.
When clicking on a TextView, you can find out its position in the LinearLayout and color each view before it with the corresponding color code in the array, along with the selected view, and the others remain grey.
I had a similar problem once with a progress bar consisting of 10 sections, and instead of looking for a library I made something quick like this and it worked just fine.
I found solution for that we need to make Custom Rating bar Here bellow code shows Custom class of Rating bar. which full fill all requirement which mention in Question.
public class MyCustomRatingBar extends android.support.v7.widget.AppCompatRatingBar {
private int[] iconArrayActive = {
R.drawable.ic_square_sel_1,
R.drawable.ic_square_sel_2,
R.drawable.ic_square_sel_3,
R.drawable.ic_square_sel_4,
R.drawable.ic_square_sel_5,
R.drawable.ic_square_sel_6,
R.drawable.ic_square_sel_7,
R.drawable.ic_square_sel_8,
R.drawable.ic_square_sel_9
};
private int[] iconArrayInactive = {
R.drawable.ic_square_unsel,
R.drawable.ic_square_unsel,
R.drawable.ic_square_unsel,
R.drawable.ic_square_unsel,
R.drawable.ic_square_unsel,
R.drawable.ic_square_unsel,
R.drawable.ic_square_unsel,
R.drawable.ic_square_unsel,
R.drawable.ic_square_unsel
};
public MyCustomRatingBar (Context context) {
super(context);
init();
}
public MyCustomRatingBar (Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public MyCustomRatingBar (Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
this.setMax(9);
this.setNumStars(9);
this.setStepSize(1.0f);
this.setRating(1.0f);
}
private Bitmap getBitmapFromVectorDrawable(Context context, int drawableId) {
Drawable drawable = ContextCompat.getDrawable(context, drawableId);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
drawable = (DrawableCompat.wrap(drawable)).mutate();
}
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;
}
#Override
protected synchronized void onDraw(Canvas canvas) {
int stars = getNumStars();
float rating = getRating();
float x = 0;
Bitmap bitmap;
Paint paint = new Paint();
int W = getWidth();
int H = getHeight();
int icon_size = (W/stars)-0;
int y_pos = (H/2)-icon_size/2;
int delta = ((H > W)?(H):(W))/(stars);
int offset = (W-(icon_size+(stars-1)*delta))/2;
for(int i = 0; i < stars; i++) {
if ((int) rating-1 >= i) {
bitmap = getBitmapFromVectorDrawable(getContext(), iconArrayActive[i]);
} else {
bitmap = getBitmapFromVectorDrawable(getContext(), iconArrayInactive[i]);
}
x = offset+(i*delta);
Bitmap scaled = Bitmap.createScaledBitmap(bitmap, icon_size, icon_size, true);
canvas.drawBitmap(scaled, x, y_pos, paint);
canvas.save();
}
}
}
Related
I am trying to build a circle containing numerous dots that eventually will be clickable (as much as 108 dots to fill out the border of a circle).
What i have done so far is to create 108 imageviews like this:
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/circle_1"
android:src="#drawable/dot_complete"
android:layout_marginLeft="383dp"
android:layout_marginTop="214dp"
/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/circle_2"
android:src="#drawable/dot_complete"
android:layout_marginLeft="382dp"
android:layout_marginTop="214dp"
/>
<!-- And so on all the way up to 108 -->
The result looks like this
However i suspect this is a very bad method, so my question is what would be the better way to do this, considering i need to have onclickListener on each dot in order to show its info.
Thank you
I had a similar class laying around, with a small modification it can display three different types of drawables as "dots". The only thing you would have to do is to write the touch management.
Drawing 108 dots (three different types):
public class DotsView extends View {
private static final int dots = 108;
private static final int dotRadius = 20;
private Bitmap testBitmap1;
private Bitmap testBitmap2;
private Bitmap testBitmap3;
private RectF dotRect;
private Paint paint;
private int[] dotsStates = new int[dots];
public DotsView(Context context) {
super(context);
setupView(context);
}
public DotsView(Context context, AttributeSet attrs) {
super(context, attrs);
setupView(context);
}
public DotsView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setupView(context);
}
private void setupView(Context context) {
setWillNotDraw(false);
paint = new Paint();
paint.setAntiAlias(true);
test();
}
private void test() {
//THIS METHOD IS JUST A TEST THAT CHANGES THE DRAWABLES USED FOR SOME DOTS
for (int i = 2; i < 20; ++i) {
dotsStates[i] = 1;
}
for (int i = 50; i < 55; ++i) {
dotsStates[i] = 2;
}
}
#Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
initBitmaps();
invalidate();
}
#Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
destroyBitmaps();
}
private void initBitmaps() {
testBitmap1 = BitmapFactory.decodeResource(getResources(), R.drawable.test_1);
testBitmap2 = BitmapFactory.decodeResource(getResources(), R.drawable.test_2);
testBitmap3 = BitmapFactory.decodeResource(getResources(), R.drawable.test_3);
dotRect = new RectF(0, 0, dotRadius, dotRadius);
}
private boolean isBitmapValid(Bitmap bitmap) {
return bitmap != null && !bitmap.isRecycled();
}
private void destroyBitmaps() {
if (isBitmapValid(testBitmap1)) {
testBitmap1.recycle();
testBitmap1 = null;
}
if (isBitmapValid(testBitmap2)) {
testBitmap2.recycle();
testBitmap2 = null;
}
if (isBitmapValid(testBitmap3)) {
testBitmap3.recycle();
testBitmap3 = null;
}
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (isBitmapValid(testBitmap1) && isBitmapValid(testBitmap2) && isBitmapValid(testBitmap3)) {
// apply padding to canvas:
final int width = canvas.getWidth();
final int height = canvas.getHeight();
final int squareSide = Math.min(width, height);
canvas.translate(width / 2f, height / 2f); // moving to the center of the View
final float outerRadius = squareSide / 2f;
final float innerRadius = outerRadius - dotRadius;
final float angleFactor = 360f / dots;
for (int i = 0; i < dots; ++i) {
canvas.save(); // creating a "checkpoint"
canvas.rotate(angleFactor * i);
canvas.translate(innerRadius, 0); //moving to the edge of the big circle
canvas.drawBitmap(dotsStates[i] == 0 ?
testBitmap1 :
dotsStates[i] == 1 ?
testBitmap2 : testBitmap3,
null, dotRect, paint);
canvas.restore(); //restoring a "checkpoint"
}
}
}
}
Your approach is super heavyweight. I'd instead recommend making a custom View class, within which you do these things:
Override the onDraw method to draw your circles directly onto the view's Canvas
Implement an onTouchEvent listener, checking the coordinates of the touch against the positions/radii of the circles you created - thus finding the circle (if any) which was tapped
Trigger a custom event like onCircleTapped(View v, int circleId) so that the containing view/activity/fragment can handle the event properly.
You can try this librarytire view
import the barlibrary
create ChartTireView
I hope this will help you.
I have added a seekbar to one of my activities.
Its max value is 5. Now, I want to display the divider values (with increment 1, like 0, 1, 2, 3, 4 and 5) below my seekbar. How can I do that?
Is there any system method to achieve this which I am not able to put my hands on? Any inputs are welcomed.
NOTE : I want to apply any changes programatically, not from xml. The numbers should be separated at equal intervals. I could not edit it that precisely though.
I am supposing you want to display view like below in picture.
if that is the case you have to create your own customSeekbar like give code.
CustomSeekBar.java
public class CustomSeekBar extends SeekBar {
private Paint textPaint;
private Rect textBounds = new Rect();
private String text = "";
public CustomSeekBar(Context context) {
super(context);
textPaint = new Paint();
textPaint.setColor(Color.WHITE);
}
public CustomSeekBar(Context context, AttributeSet attrs) {
super(context, attrs);
textPaint = new Paint();
textPaint.setTypeface(Typeface.SANS_SERIF);
textPaint.setColor(Color.BLACK);
}
public CustomSeekBar(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
textPaint = new Paint();
textPaint.setColor(Color.BLACK);
}
#Override
protected synchronized void onDraw(Canvas canvas) {
// First draw the regular progress bar, then custom draw our text
super.onDraw(canvas);
int progress = getProgress();
text = progress + "";
// Now get size of seek bar.
float width = getWidth();
float height = getHeight();
// Set text size.
textPaint.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.BOLD));
textPaint.setTextSize(40);
// Get size of text.
textPaint.getTextBounds(text, 0, text.length(), textBounds);
// Calculate where to start printing text.
float position = (width / getMax()) * getProgress();
// Get start and end points of where text will be printed.
float textXStart = position - textBounds.centerX();
float textXEnd = position + textBounds.centerX();
// Check does not start drawing outside seek bar.
if (textXStart <= 1) textXStart = 20;
if (textXEnd > width) {
textXStart -= (textXEnd - width + 30);
}
// Calculate y text print position.
float yPosition = height;
canvas.drawText(text, textXStart, yPosition, textPaint);
}
public synchronized void setTextColor(int color) {
super.drawableStateChanged();
textPaint.setColor(color);
drawableStateChanged();
}
}
In your Xml file use your custom file like below
<com.waleedsarwar.customseekbar.CustomSeekBar
android:id="#+id/seekbar"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:max="5"
android:paddingBottom="16dp" />
This is another approach. I am extending a linearlayout. I put seekbar and another linearlayout(layout_5) which contains 6 textviews with 0-1-2-3-4-5. Better option would be creating a dynamic image(get width from seekBar) which has these numbers according to segment count.
I force seekbar's indicator to stop at specific points(6 points in your case). Instead of doing this, it is possible to set seekBar's maximum progress value to 5. It will work, but it will not give a good user experience.
public class SegmentedSeekBar extends LinearLayout {
private int[] preDefinedValues;
private int currentProgressIndex;
private SeekBar seekBar;
private int segmentCount = 5:
public SegmentedSeekBar(Context context) {
this(context, null, 0);
}
public SegmentedSeekBar(Context context, AttributeSet attrs) {
this(context, attrs, android.R.attr.seekBarStyle);
}
public SegmentedSeekBar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray a = context.getTheme().obtainStyledAttributes(
attrs,
R.styleable.SegmentedSeekBar,
0, 0);
try {
segmentCount =
a.getInt(R.styleable.SegmentedSeekBar_segmentCount, -1);
} finally {
a.recycle();
}
init();
}
public void init() {
//this values will be used when you need to set progress
preDefinedValues = new int[segmentCount];
for(int i = 0; i < preDefinedValues.length; i++) {
preDefinedValues[i] = (100/(segmentCount-1)) * i;
}
//Get layout_5
//which is linearlayout with 6 textviews
LayoutInflater inflater = (LayoutInflater) getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View sliderView = inflater.inflate(
getSliderId(segmentCount), null);
//seekbar already inside the linearlayout
seekBar = (SeekBar)sliderView.findViewById(R.id.seek_bar);
//linear layout is vertically align
//so add your 6 textview linearlayout
addView(sliderView);
seekBar.setOnTouchListener(seekBarTouchListener);
}
private int getSliderId(int size) {
return R.layout.layout_5;
}
//this method sets progress which is seen in UI not actual progress
//It uses the conversion that we did in beginning
public synchronized void setProgress(int progress) {
if(preDefinedValues != null && progress < preDefinedValues.length && progress >= 0) {
seekBar.setProgress(preDefinedValues[progress]);
currentProgressIndex = progress;
}
}
//this listener make sure the right progress is seen in ui
//take action when user finish with changing progress
SeekBar.OnSeekBarChangeListener onSeekBarChangeListener = new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
int index = 0;
for(int i = 0; i < preDefinedValues.length; i++) {
//try to find closest preDefinedvalues by comparing with latest value
if(Math.abs(seekBar.getProgress() - preDefinedValues[i]) < Math.abs(seekBar.getProgress() - preDefinedValues[index])) {
index = i;
}
}
setProgress(index);
}
};
}
I want to have something where half of the text in a textView or any other kind of text display is highlighted while the other half is not. For example
in "textView". the "text" would be in a red font and "view" would be in black.
I was thinking about doing this by putting 2 textViews directly on top of each other but I am not exactly sure how to do this. (What kind of parameters, etc?) Any ideas?
Thank you
You can stack multiple textViews by using a Layout that supports this, such as a FrameLayout or RelativeLayout. That said, I think the better approach (which would provide better control over the appearance) would be to create a custom view, and draw the text to the canvas yourself. You can do this with something like this (I have not tested this, but it should work - might need a few tweaks though):
public class TwoPartTextView extends View
{
private CharSequence part1 = "", part2 = "";
private Paint mPaint;
private int color1 = Color.BLACK, color2 = Color.BLACK;
private Context context;
private float part1Size = 12f, part2Size = 12f;
private int strokeWidth = 2;
public TwoPartTextView(Context context) {
super(context);
init(context);
}
public TwoPartTextView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public TwoPartTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context);
}
private void init(context) {
this.context = context;
mPaint = new Paint();
}
public void setText(CharSequence part1, int color1, part1Size, CharSequence part2, int color2, part2Size, strokeWidth) {
this.part1 = part1;
this.color1 = color1;
this.part1Size = part1Size;
this.part2 = part2;
this.color2 = color2;
this.part2Size = part2Size;
this.strokeWidth = strokeWidth;
mPaint.setStrokeWidth(strokeWidth);
}
#Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
mPaint.setColor(color1);
mPaint.setTextSize(part1Size);
canvas.drawText(part1.toString(), 0, paint.getTextSize(), paint);
mPaint.setColor(color2);
mPaint.setTextSize(part2Size);
canvas.drawText(part2.toString(), getWidth()/2 /* tweak as needed*/, paint.getTextSize(), paint);
}
}
Then to use it, add it to XML or create it in code, then call:
myTwoPartTextView.setText("text", Color.RED, 12f, "View", Color.BLACK, 14f, 2);
myTwoPartTextView.setText.invalidate();
What I want to do? (blue will be changed as white)
What I did?
I have found a class which extends TextView that able to outline textview very close to what I want. The problem is that I could not change stroke color to any color, it draws always as black. How to set border color as white?
What is my output:
Where are my codes?
public class TypeFaceTextView extends TextView {
private static Paint getWhiteBorderPaint(){
Paint p = new Paint(Color.WHITE);
return p;
}
private static final Paint BLACK_BORDER_PAINT = getWhiteBorderPaint();
static {
BLACK_BORDER_PAINT.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
}
#Override
public void setText(CharSequence text, BufferType type) {
super.setText(String.format(text.toString()), type);
}
private static final int BORDER_WIDTH = 1;
private Typeface typeface;
public TypeFaceTextView(Context context) {
super(context);
}
public TypeFaceTextView(Context context, AttributeSet attrs) {
super(context, attrs);
setDrawingCacheEnabled(false);
setTypeface(attrs);
}
private void setTypeface(AttributeSet attrs) {
final String typefaceFileName = attrs.getAttributeValue(null, "typeface");
if (typefaceFileName != null) {
typeface = Typeface.createFromAsset(getContext().getAssets(), typefaceFileName);
}
setTypeface(typeface);
}
public TypeFaceTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setTypeface(attrs);
}
#Override
public void draw(Canvas aCanvas) {
aCanvas.saveLayer(null, BLACK_BORDER_PAINT, Canvas.HAS_ALPHA_LAYER_SAVE_FLAG
| Canvas.FULL_COLOR_LAYER_SAVE_FLAG | Canvas.MATRIX_SAVE_FLAG);
drawBackground(aCanvas, -BORDER_WIDTH, -BORDER_WIDTH);
drawBackground(aCanvas, BORDER_WIDTH + BORDER_WIDTH, 0);
drawBackground(aCanvas, 0, BORDER_WIDTH + BORDER_WIDTH);
drawBackground(aCanvas, -BORDER_WIDTH - BORDER_WIDTH, 0);
aCanvas.restore();
super.draw(aCanvas);
}
private void drawBackground(Canvas aCanvas, int aDX, int aDY) {
aCanvas.translate(aDX, aDY);
super.draw(aCanvas);
}
}
I found simple way to outline view without inheritance from TextView.
I had wrote simple library that use Android's Spannable for outlining text.
This solution gives possibility to outline only part of text.
Library: OutlineSpan
Class (you can copy only class):OutlineSpan
1) create your textview object extends TextView
public class YourTextView extends TextView { .........
2) Do this on its draw method
#Override
public void draw(Canvas canvas) {
for (int i = 0; i < 5; i++) {
super.draw(canvas);
}
}
3) set textview's xml side as below
android:shadowColor="#color/white"
android:shadowRadius="5"
My solution based on custom TextView.
public class TextViewOutline extends TextView{
int outline_color;
float outline_width; //relative to font size
public TextViewOutline( Context context, int outline_color, float outline_width ){
super( context );
this.outline_color = outline_color;
this.outline_width = outline_width;
}
#Override
protected void onDraw( Canvas canvas) {
//draw standard text
super.onDraw( canvas );
//draw outline
Paint paint = getPaint();
paint.setStyle( Paint.Style.STROKE );
paint.setStrokeWidth( paint.getTextSize()*outline_width );
int color_tmp = paint.getColor();
setTextColor( outline_color );
super.onDraw( canvas );
//restore
setTextColor( color_tmp );
paint.setStyle( Paint.Style.FILL );
}
}
Code for test.
TextViewOutline tv = new TextViewOutline( this, 0xff0080ff, 0.04f);
tv.setText( "Simple TEST" );
tv.setTypeface( Typeface.create( Typeface.SERIF, Typeface.BOLD ) );
tv.setTextColor( 0xff000000 );
tv.setTextSize( 128 );
setContentView(tv);
tv.setOnClickListener( new View.OnClickListener(){
#Override
public void onClick( View view ){
view.invalidate();
}
} );
Result.
Couldn't this this but try experimenting with: PorterDuff.Mode
http://developer.android.com/reference/android/graphics/PorterDuff.Mode.html
Try changing it to 'ADD' or 'CLEAR', hope this helps.
You need to change your getWhiteBorderPaint() method to the following:
private static Paint getWhiteBorderPaint(){
Paint p = new Paint();
p.setColor(Color.WHITE);
return p;
}
The Paint constructor only takes bitmasked flags and doesn't support arbitrary ints as parameters.
Investigated into the original problem stated by this question. Found the solution.
First, change DST_OUT to DARKEN
static {
BLACK_BORDER_PAINT.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DARKEN));
}
Secondly, save the original text color, and put the intended outline color up, draw the outline, and then restore the original text color.
#Override
public void draw(Canvas aCanvas) {
int originalColor = this.getCurrentTextColor();
this.setTextColor(0xff000000); //set it to white.
aCanvas.saveLayer(null, borderPaint, Canvas.HAS_ALPHA_LAYER_SAVE_FLAG
| Canvas.FULL_COLOR_LAYER_SAVE_FLAG | Canvas.MATRIX_SAVE_FLAG);
drawBackground(aCanvas, -BORDER_WIDTH, -BORDER_WIDTH);
drawBackground(aCanvas, BORDER_WIDTH + BORDER_WIDTH, 0);
drawBackground(aCanvas, 0, BORDER_WIDTH + BORDER_WIDTH);
drawBackground(aCanvas, -BORDER_WIDTH - BORDER_WIDTH, 0);
this.setTextColor(originalColor);
aCanvas.restore();
super.draw(aCanvas);
}
text outline with transparent background
this is one way to do it with no background color
public class CustomTextView extends androidx.appcompat.widget.AppCompatTextView {
float mStroke;
public CustomTextView(Context context, #Nullable AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.CustomTextView);
mStroke=a.getFloat(R.styleable.CustomTextView_stroke,1.0f);
a.recycle();
}
#Override
protected void onDraw(Canvas canvas) {
TextPaint paint = this.getPaint();
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(mStroke);
super.onDraw(canvas);
}
}
then you only need to add the following to the attrs.xml file
<declare-styleable name="CustomTextView">
<attr name="stroke" format="float"/>
</declare-styleable>
and now you will be able to set the stroke widht by app:stroke while retaining all other desirable properties of TextView. my solution only draws the stroke w/o a fill. this makes it a bit simpler than the others. bellow a screencapture with the result while setting a custom font to my customtextview on a dark background.
I'm trying to draw a rounded rect with a specific color, but i'm getting nothing.
I've already done lots of googling, and found some questions like this and read them all. However, none of them solved my problem. Why my onDraw method is never called?
Any help is appreciated.
public class RoundedTagItem extends RelativeLayout {
Context ctx;
String colorString;
int color;
public RoundedTagItem(Context context) {
super(context);
this.ctx = context;
color = Color.WHITE;
this.setWillNotDraw(false);
this.setPadding(10, 0, 10, 0);
}
public RoundedTagItem(Context context, String color) {
super(context);
this.ctx = context;
this.colorString = color;
this.setWillNotDraw(false);
this.setPadding(10, 0, 10, 0);
}
#Override
protected void onDraw(Canvas canvas) {
if(colorString != null)
color = Color.parseColor("#" + colorString);
int rectValue = 35;
Log.d("Rounded", "rectValue: " + rectValue);
RectF rect1 = new RectF(0, 0, rectValue, rectValue);
Paint paint = new Paint();
paint.setStrokeWidth(1);
paint.setStrokeCap(Paint.Cap.ROUND);
paint.setStyle(Paint.Style.FILL);
paint.setAntiAlias(true);
paint.setColor(color);
canvas.save();
canvas.drawRoundRect(rect1, 10, 10, paint);
canvas.restore();
super.onDraw(canvas);
}
public void ChangeBackgroundColor(String colorString) {
color = Color.parseColor(colorString);
invalidate();
}
}
And then I put icons on this custom view on my main class:
// add category items to view
LinearLayout categories = (LinearLayout) findViewById(R.id.detailTagImagesLayout);
for(int i = 0; i < item.getCategoryItems().size(); i++) {
RoundedTagItem v = null;
if(i == 0)
v = new RoundedTagItem(DetailActivity.this,
item.getCategoryItems().get(i).getColorCode());
else
v = new RoundedTagItem(DetailActivity.this);
ImageView img = new ImageView(DetailActivity.this);
img.setImageDrawable(Drawable.createFromPath(
item.getCategoryItems().get(i).getLightIconUrl()));
v.addView(img);
v.setTag(i);
v.setOnClickListener(new TagClickListener());
categories.addView(v);
}
Some improvements/problems you can make/fix...
You can move these lines to your constructor:
if(colorString != null)
color = Color.parseColor("#" + colorString);
Since this colorString never changes and the way you are doing it now you are calculating it every time onDraw is called (and he will be called a lot of times).
Second please move your super.onDraw(canvas) to your first line.
Third you need to define your LayoutParams on your constructor. If a View has 0 width/height its draw will never be called!
this.setLayoutParams(new LayoutParams(150, 150));
At last please make sure you are using your RoundTagItem. You can add this view to your xml using a tag like this: <your.package.RoundTagItem> where your.package is the package that you are using (com.something.blabla). If you use it like this please be sure you define the layout_width and the layout_height.
You can also add your view programmatcly by adding to your root view (you get it by using findViewById(R.layout.your_root)) or by setting your view as the main content.
RoundedTagItem myView = new RoundedTagItem(this);
setContentView(myView);
Try to create a simple single RelativeLayout XML (rounded_tag_item.xml), and inflate the custom view:
public class RoundedTagItem extends RelativeLayout {
public RoundedTagItem(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public RoundedTagItem(Context context) {
super(context);
init(context);
}
private void init(Context context) {
LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (inflater != null) {
RelativeLayout layout = (RelativeLayout) inflater.inflate(R.layout.rounded_tag_item, new RelativeLayout(context));
// rest of stuff...
}
}
}