Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Subclassed RelativeLayout onDraw() method not called in ListView

Here's a little background into what I'm trying to achieve, in order to help make my question a bit more clear...I'm creating a Navigation Drawer where each item in the ListView looks similar to the following:

ListItem

However, I need to be able to change the color of the right side border (the blue) to a variety of different colors programmatically, so while playing around with a solution, I decided to extend a RelativeLayout and draw the line in the onDraw(Canvas c); method. My RelativeLayout code is as follows:

public class CustomRelativeLayout extends RelativeLayout {

    private final Paint paint = new Paint();

    public CustomRelativeLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

        //Other Constructors

    private void init() {
        setPaintColor(Color.argb(128, 0, 0, 0));
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(3);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawLine(getMeasuredWidth() - 1, 0, getMeasuredWidth() - 1, getMeasuredHeight(), paint);
    }

    public void setPaintColor(int color){
        paint.setColor(color);
        invalidate();
    }
}

My NavigationDrawer's ListView also contains a header that uses this class, and it works fine as a header view. However, for each individual ListView item, the border isn't present. I've debugged my solution, and found that my subclassed RelativeLayout's onDraw(Canvas c); method is called for the header view, but isn't called for each of the ListView's child views provided by my ArrayAdapter<String>.

I know there are other ways to handle this, such as using a default View, setting it's background to the color I want, and aligning it to the right - but that's not my question. My question is why is my CustomRelativeLayout's onDraw(Canvas c); method is called for the ListView's header view, and not for each of the Views provided by my adapter? Any insight into this behavior would be appreciated. Also, here are the CustomArrayAdapter and nav_drawer_item.xml used with the ListView in case they're helpful:

public class SimpleDrawerAdapter extends ArrayAdapter<String> {

    public SimpleDrawerAdapter(Context context, int resource,
            String[] sections) {
        super(context, resource, sections);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        RelativeLayout container = null;

        if(convertView == null){
            LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
            container = (CustomRelativeLayout) inflater.inflate(R.layout.nav_drawer_item, parent, false);
        } else {
            container = (CustomRelativeLayout) convertView;
        }

        ((TextView)container.findViewById(R.id.nav_item_text)).setText(getItem(position));

        return container;
    }

}

nav_drawer_item.xml

<?xml version="1.0" encoding="utf-8"?>
<com.mypackage.views.CustomRelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="@dimen/navigation_drawer_width"
    android:layout_height="wrap_content">

    <TextView 
        android:id="@+id/nav_item_text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textColor="@color/nav_drawer_grey"
        android:textSize="@dimen/text_large"
        android:layout_margin="@dimen/navigation_drawer_item_margin"
        android:paddingTop="4dp"
        android:paddingBottom="4dp" />

</com.mypackage.views.CustomRelativeLayout>
like image 859
Submersed Avatar asked Dec 04 '25 11:12

Submersed


1 Answers

Have you tried clearing the WILL_NOT_DRAW flag by calling setWillNotDraw method in your custom layout?

If this view doesn't do any drawing on its own, set this flag to allow further optimizations. By default, this flag is not set on View, but could be set on some View subclasses such as ViewGroup. Typically, if you override onDraw(android.graphics.Canvas) you should clear this flag.

like image 122
Tadej Avatar answered Dec 06 '25 01:12

Tadej



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!