#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() или где-то еще?