У меня есть 4 TextViews
в GridView
с пользовательским адаптером в данном Fragment
. Моя основная Activity
получает уведомление через TimerTask
чтобы обновить цвет текста для правильного TextView
. Это отлично TextViews
для всех TextViews
кроме первого, когда приложение запускается. После этого он работает правильно, как и остальные TextViews
.
В рассматриваемом Fragment
:
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment View view = inflater.inflate(R.layout.short_press_info_fragment, container, false); GridView grid = (GridView) view.findViewById(R.id.grid_view); infoAdapter = new ShortPressInfoAdapter(mKeyInfo, getActivity()); grid.setAdapter(infoAdapter); return view; }
В адаптере:
public View getView(int position, View convertView, ViewGroup parent) { View v = convertView; if(convertView == null) { Log.d("GRID_VIEW", "inflating"); LayoutInflater li = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); v = li.inflate(R.layout.grid_item, null); TextView text = texts[position] = (TextView) v.findViewById(R.id.gridItemText); Log.d("GRID_VIEW", "creating view"); text.setText(mKeyInfo[position]); switch(position) { case 0: text.setBackgroundColor(mContext.getResources().getColor(R.color.blue)); break; case 1: text.setBackgroundColor(mContext.getResources().getColor(R.color.yellow)); break; case 2: text.setBackgroundColor(mContext.getResources().getColor(R.color.green)); break; case 3: text.setBackgroundColor(mContext.getResources().getColor(R.color.red)); break; default: break; } } return v; }
В основной Activity
:
public void emphasizeShort(final PressID p, final boolean b) { runOnUiThread(new Runnable() { @Override public void run() { if(b) { Log.d(TAG, "setting short " + p + " to black"); getShortTextView(p).setTextColor(getResources().getColor(R.color.black)); } else { Log.d(TAG, "setting short " + p + " to white"); getShortTextView(p).setTextColor(getResources().getColor(R.color.white)); } } }); }
Журнал показывает мне тот же результат, независимо от того, какой TextView
я пытаюсь изменить, когда приложение запускается, но первый TextView
является единственным, который просто не меняется.
Что может заставить View
игнорировать изменения при запуске приложения, но не после? И из этого кода я не понимаю, почему выделяется первый TextView
.
Любая помощь будет принята с благодарностью.
EDIT: вот функция, которая отправляет запрос, чтобы подчеркнуть TextView
.
@Override public boolean onTouch(final View v, final MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { // button pressed pressTime = System.currentTimeMillis(); timer = new Timer(); timer.schedule(new TimerTask() { @Override public void run() { Log.d("TIMER_TASK", "short press " + (System.currentTimeMillis() - pressTime)); mFourButtonListener.onShortPress(buttonID); } }, SHORT_PRESS_DELAY); timer.schedule(new TimerTask() { @Override public void run() { Log.d("TIMER_TASK", "long press " + (System.currentTimeMillis() - pressTime)); mFourButtonListener.onLongPress(buttonID); } }, LONG_PRESS_DELAY); return true; } else if (event.getAction() == MotionEvent.ACTION_UP) { duration = System.currentTimeMillis() - pressTime; timer.cancel(); timer.purge(); if (duration >= SHORT_PRESS_DELAY && duration < LONG_PRESS_DELAY) mFourButtonListener.onShortRelease(buttonID); else if (duration >= LONG_PRESS_DELAY) mFourButtonListener.onLongRelease(buttonID); return true; } return false; } }
Я в отчаянии.
Здесь много недостающего кода, но если у вас возникла проблема с тем, что он не работает, когда приложение runOnUiThread
первым, проблема, скорее всего, вызвана runOnUiThread
, который просто не является надежным при запуске. (Т. Е. Гарантируется, что не будет выполняться каждая поставленная задача).
Добавить переменную Handler
уровня класса
Handler h;
И создать его во время onCreate
h = new Handler();
Затем используйте h.post()
вместо runOnUiThread
.
Если нет. Из TextView
s останется 4, независимо от того, что тогда не использует GridView
. LineareLayout
этого используйте LineareLayout
. В любом случае ваш текущий подход перестанет работать, если вы добавите больше TextView
. На первый взгляд ваш getView()
неисправен, вы должны сделать это следующим образом:
public View getView(int position, View convertView, ViewGroup parent) { View v = convertView; if(convertView == null) { Log.d("GRID_VIEW", "inflating"); LayoutInflater li = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); v = li.inflate(R.layout.grid_item, null); } // <<<<------------------- TextView text = (TextView) v.findViewById(R.id.gridItemText); Log.d("GRID_VIEW", "creating view"); text.setText(mKeyInfo[position]); switch(position) { case 0: text.setBackgroundColor(mContext.getResources().getColor(R.color.blue)); break; case 1: text.setBackgroundColor(mContext.getResources().getColor(R.color.yellow)); break; case 2: text.setBackgroundColor(mContext.getResources().getColor(R.color.green)); break; case 3: text.setBackgroundColor(mContext.getResources().getColor(R.color.red)); break; default: break; } return v; }
В основном вы должны выполнять все связанные с состоянием операции каждый раз, когда getView()
вызывается из-за View
утилизации.
Кстати, почему вы держите ссылку на себя в массиве texts
? Это очень плохая практика . Зачем тебе это нужно?
Если вы хотите изменить цвета на более позднем этапе, вам нужно изменить всю свою логику. Вам нужно сделать что-то похожее на это:
import android.content.Context; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; public class MyAdapter extends BaseAdapter { int[] colors = new int[4]; public MyAdapter(Context context) { colors[0] = context.getResources().getColor(R.color.blue); colors[1] = context.getResources().getColor(R.color.yellow); colors[2] = context.getResources().getColor(R.color.green); colors[3] = context.getResources().getColor(R.color.red); } @Override public int getCount() { return colors.length; } @Override public Object getItem(int position) { return colors[position]; } @Override public long getItemId(int position) { return position; } public View getView(int position, View convertView, ViewGroup parent) { View v = convertView; if(convertView == null) { Log.d("GRID_VIEW", "inflating"); LayoutInflater li = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); v = li.inflate(R.layout.grid_item, null); } // <<<<------------------- TextView text = (TextView) v.findViewById(R.id.gridItemText); Log.d("GRID_VIEW", "creating view"); text.setText(mKeyInfo[position]); text.setBackgroundColor(colors[position]); return v; } // call this method to change colors at later stage public void changeColor(int position, int color){ colors[position] = color; notifyDataSetChanged(); } // call this method to change text at later stage public void changeText(int position, String text){ mKeyInfo[position] = text; notifyDataSetChanged(); } }