1

I am trying to add a border programmatically to certain row elements in an ArrayAdapter that is displayed within an AlertDialog. Basically I want to take this :

enter image description here

And make it like this (so placing white borders on the left and right side of the views for certain rows, black border above VARIABLEenter image description here):

Here is the code. This is just debu code, so don't worry too much about efficiency since it will only be run locally and only for debugging:

public class RuleDebugItemAdapter extends ArrayAdapter<RuleDebugItem> {
Context mContext; 
int mLayoutResourceId;    
ArrayList<RuleDebugItem> mData;

public RuleDebugItemAdapter(Context context, int resource, ArrayList<RuleDebugItem> data) {
    super(context, resource, data);
    mContext = context;
    mLayoutResourceId = resource;
    mData = data;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View v = super.getView(position, convertView, parent);
    TextView tv = (TextView) v.findViewById(android.R.id.text1);
    RuleDebugItem item = mData.get(position);

    tv.setSingleLine(false);
    if (item.type.equalsIgnoreCase(Field.VARIABLE)) {
        tv.setText(item.ruleDebugText);
        tv.setTextSize(18);
        tv.setTypeface(null, Typeface.BOLD);
        v.setBackgroundColor(ContextCompat.getColor(mContext,android.R.color.white));
        tv.setTextColor(ContextCompat.getColor(mContext,android.R.color.black));
    }
    else if (item.type.equalsIgnoreCase(Field.FORMRULE)) { 
        tv.setText(item.ruleDebugText);
        tv.setTextSize(18);
        tv.setTypeface(null, Typeface.BOLD);
        v.setBackgroundColor(ContextCompat.getColor(mContext,android.R.color.white));
        tv.setTextColor(ContextCompat.getColor(mContext,android.R.color.black));
    }
    else if (item.type.equalsIgnoreCase(Field.CONDITION_BLOCK)) { 
        tv.setText(item.ruleDebugText);
        tv.setTextSize(18);
        tv.setTypeface(null, Typeface.BOLD);
        v.setBackgroundColor(ContextCompat.getColor(mContext,android.R.color.holo_orange_light));
        tv.setTextColor(ContextCompat.getColor(mContext,android.R.color.white));
    }
    else if (item.type.equalsIgnoreCase(Field.FUNCTION)) {

        tv.setTextSize(16);
        if (item.success) {
            v.setBackgroundColor(ContextCompat.getColor(mContext,android.R.color.holo_green_light));
            tv.setText(Field.SPACE + item.ruleDebugText);
        }
        else {
            v.setBackgroundColor(ContextCompat.getColor(mContext,android.R.color.holo_blue_bright));
            tv.setText("Init " + item.ruleDebugText);
        }

        tv.setTypeface(null, Typeface.BOLD);
        tv.setTextColor(ContextCompat.getColor(mContext,android.R.color.white));
    }
    else if (item.type.equalsIgnoreCase(Field.ACTION)) {

        tv.setTextSize(16);
        if (item.success) {
            v.setBackgroundColor(ContextCompat.getColor(mContext,android.R.color.holo_green_light));
            tv.setText(Field.SPACE + item.ruleDebugText);
        }
        else {
            v.setBackgroundColor(ContextCompat.getColor(mContext,android.R.color.holo_blue_bright));
            tv.setText("Pre-" + item.ruleDebugText);
        }

        tv.setTypeface(null, Typeface.BOLD);
        tv.setTextColor(ContextCompat.getColor(mContext,android.R.color.white));
    }
    else if (item.type.equals(Field.CONDITION)) {
        tv.setText(item.ruleDebugText);
        tv.setTextSize(16);
        tv.setTypeface(null, Typeface.NORMAL);
        if (item.success)
            v.setBackgroundColor(ContextCompat.getColor(mContext,android.R.color.holo_green_light));
        else 
            v.setBackgroundColor(ContextCompat.getColor(mContext,android.R.color.holo_red_light));
        tv.setTextColor(ContextCompat.getColor(mContext,android.R.color.white));
    }
    return v;
}
}

All in an effort to make is a bit more readable. Yeah, I know the colors are ugly and I could do a tree instead.. :)

Stephen McCormick
  • 1,706
  • 22
  • 38

2 Answers2

0

With adapters you have the concept of view types. You can get your adapter to play along by overriding getViewTypeCount and getItemViewType.

So let's say you make another layout just like your item list layout, only it has the black border on top.

First you add this:

        @Override
        public int getViewTypeCount() {
            return 2;
        }

        @Override
        public int getItemViewType(int position) {
            RuleDebugItem item = mData.get(position);
            if (item.type.equalsIgnoreCase(Field.VARIABLE)) {
                return 0;
            }
            return 1;
        }

Now in your getView you can inflate the layout with the border when you have a variable item, and inflate the other layout for everything else.

Because your adapter has told the ListView about the view types, you can expect that when a view gets recycled, you will get the correct layout in each case.

You could even extend this to have three layouts, one for each type and handle the background color and text color in the layout, which would make your code much simpler.

kris larson
  • 30,387
  • 5
  • 62
  • 74
0

Try this:

ViewGroup.MarginLayoutParams marginLayoutParams = (ViewGroup.MarginLayoutParams) tv
                .getLayoutParams();
        marginLayoutParams.setMargins(10, 0, 10, 0);

You can adjust margin size as per your need.

Myth
  • 1,218
  • 12
  • 15