我正在创建一个简单的国际象棋钟型计时器应用程序。我正在尝试显示玩家及其离开的时间ListView
。我正在使用扩展RelativeLayout
到这些行的自定义视图,例如,我可以给它提供依次突出显示播放器的方法。
行布局类:
public class GameTimerView extends RelativeLayout {
private TextView nameView;
private TextView timerView;
public GameTimerView(Context context) {
super(context);
LayoutInflater inflater = LayoutInflater.from(context);
inflater.inflate(R.layout.timer_view, this);
loadViews();
}
...
private void loadViews() {
nameView = (TextView)findViewById(R.id.nameView);
timerView = (TextView)findViewById(R.id.timerView);
}
public void setName(String name) {
nameView.setText(name);
}
public void setTime(long timeInMillis) {
timerView.setText(String.format("%02d:%02d",
TimeUnit.MILLISECONDS.toMinutes(timeInMillis),
TimeUnit.MILLISECONDS.toSeconds(timeInMillis) -
TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(timeInMillis))
));
}
public void setActive() {
this.nameView.setTextColor(Color.GREEN);
}
public void setInactive() {
nameView.setTextColor(Color.BLACK);
}
}
行布局XML(timer_view.xml):
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:id="@+id/nameView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_toLeftOf="@+id/timerView"
android:text="@string/player_default_name" />
<TextView
android:id="@+id/timerView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:text="@string/zero_time" />
</RelativeLayout>
适配器:
public class playerArrayAdapter extends ArrayAdapter<Player> {
private final Context context;
private final ArrayList<Player> players;
public playerArrayAdapter(Context context, ArrayList<Player> values) {
super(context, R.layout.timer_view, values);
this.context = context;
this.players = values;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
GameTimerView playerView = new GameTimerView(context);
players.get(position).setTimerView(playerView);
return playerView;
}
}
播放器类的setTimerView函数:
public void setTimerView(GameTimerView timer) {
this.timerView = timer;
this.timerView.setName(this.name);
this.timerView.setTime(this.totalCountDown);
this.timerView.setInactive();
}
在活动的onCreate方法中:
playerArrayAdapter playersAdapter = new playerArrayAdapter(
getApplicationContext(),
game.getPlayers()
);
ListView playersView = (ListView) findViewById(R.id.playerList);
playersView.setAdapter(playersAdapter);
最初,这似乎可行,并且所需的玩家名称和时间已正确呈现到列表中。但是,如果以后再以编程方式调用Player.timerView.setActive()
,则什么也不会发生。
看过数十个ListViews的自定义适配器的示例后,似乎没有一个以这种方式使用它-视图总是直接在中膨胀Apdater.getView()
。我想要扩展视图类的灵活性,但是显然我做错了。
那么,对ListView
行使用自定义视图类的正确方法是什么?
首先,给充气时GameTimerView
,您会感到RelativeLayout
内心深处。
其次,回答问题:最好不要在每次对的调用上重新创建视图ArrayAdapter.getView()
,而是playerArrayAdapter
通过添加如下所示的缓存来进行修改:
private List<View> views;
public playerArrayAdapter(Context context, ArrayList<Player> values) {
super(context, R.layout.timer_view, values);
views = new ArrayList<View>(values.length);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View playerView;
if (position < views.size()) {
playerView = views.get(position);
if (playerView != null)
return playerView;
} else {
while (views.size() < position)
views.add(null);
}
playerView = new GameTimerView(context);
views.add(position, playerView);
players.get(position).setTimerView(playerView);
return playerView;
}
如果此操作成功解决了您的问题,则意味着在以前,将播放器设置为活动状态时,ListView
将再次获取所有视图以进行渲染,重新创建视图,然后删除所有以前的状态。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句