我在TextViews
中有4个GridView
,其中包含给定Fragment
中的自定义适配器。我的主Activity
会通过TimerTask
收到通知,以更新正确TextView
的文字颜色。除了应用程序首次启动时的第一个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
在应用启动时忽略更改而不是之后?从这段代码中我不明白为什么第一个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;
}
}
s。
{{1}}
我变得绝望了。
答案 0 :(得分:3)
这里有很多遗漏的代码,但是如果你在应用首次启动时遇到问题,那么问题很可能是由runOnUiThread
造成的,这在启动时根本不可靠。 (即并非所有发布的任务都能保证运行。)
添加班级Handler
变量
Handler h;
并在onCreate
h = new Handler();
然后使用h.post()
代替runOnUiThread
。
答案 1 :(得分:2)
如果没有。 TextView
的{{1}}将保持4,无论不使用GridView
。请改用LineareLayout
。无论如何,如果添加更多TextView
s,您当前的方法将停止工作。乍一看你的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
时,您必须执行所有与状态相关的操作。
BTW为什么要在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();
}
}