Android программно добавляет границу в представление ArrayAdapter в AlertDialog

#android #android-arrayadapter #android-alertdialog #getview

#Android #android-arrayadapter #android-alertdialog #getview

Вопрос:

Я пытаюсь программно добавить границу к определенным элементам строки в ArrayAdapter, который отображается в AlertDialog. В принципе, я хочу воспользоваться этим :

введите описание изображения здесь

И сделайте это так (таким образом, разместив белые границы слева и справа от представлений для определенных строк, черную границу над ПЕРЕМЕННОЙвведите описание изображения здесь):

Вот код. Это всего лишь код debu, поэтому не слишком беспокойтесь об эффективности, поскольку он будет выполняться только локально и только для отладки:

 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;
}
}
  

Все, чтобы сделать это немного более читаемым. Да, я знаю, что цвета уродливые, и я мог бы вместо этого сделать дерево .. 🙂

Ответ №1:

С адаптерами у вас есть концепция типов представления. Вы можете заставить свой адаптер играть вместе, переопределив getViewTypeCount и getItemViewType .

Итак, допустим, вы создаете другой макет, похожий на макет списка элементов, только он имеет черную рамку сверху.

Сначала вы добавляете это:

         @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;
        }
  

Теперь в вашем getView вы можете увеличить макет с помощью границы, когда у вас есть переменный элемент, и увеличить другой макет для всего остального.

Поскольку ваш адаптер сообщил ListView о типах представления, вы можете ожидать, что при повторной обработке представления вы получите правильный макет в каждом случае.

Вы могли бы даже расширить это, чтобы иметь три макета, по одному для каждого типа, и обрабатывать цвет фона и цвет текста в макете, что значительно упростило бы ваш код.

Комментарии:

1. Спасибо, я попробую и посмотрю, что получится.

Ответ №2:

Попробуйте это:

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

Вы можете настроить размер поля в соответствии с вашими потребностями.

Комментарии:

1. К сожалению, это просто приводит к сбою приложения с исключением ClassCast. Должно ли это быть сделано в getView() или где-то еще?