java - Android:如何使用扩展布局类作为ListView行?

标签 java android listview

我正在创建一个简单的国际象棋时钟类型计时器应用程序。我试图在 ListView 中以行形式显示玩家及其剩余时间。我正在使用一个自定义 View ,该 View 为这些行扩展了 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;
    }
}

Player类setTimerView函数:

public void setTimerView(GameTimerView timer) {
    this.timerView = timer;
    this.timerView.setName(this.name);
    this.timerView.setTime(this.totalCountDown);
    this.timerView.setInactive();
}

在 Activity 的 onCreate 方法中:

playerArrayAdapter playersAdapter = new playerArrayAdapter(
        getApplicationContext(),
        game.getPlayers()
);

ListView playersView = (ListView) findViewById(R.id.playerList);
playersView.setAdapter(playersAdapter);

起初这似乎有效,并且所需的玩家姓名和时间已正确呈现到列表中。但是,如果我稍后以编程方式调用 Player.timerView.setActive(),则不会发生任何情况。

查看了数十个 ListView 自定义适配器的示例后,似乎没有一个以这种方式使用它 - View 始终直接在 Apdater.getView() 中膨胀。然而,我想要扩展 View 类的灵 active ,但显然我做错了。

那么,为 ListView 行使用自定义 View 类的正确方法是什么?

最佳答案

首先,当扩展您的 GameTimerView 时,您会在另一个组件中获得一个 RelativeLayout

其次,回答这个问题:最好不要在每次调用 ArrayAdapter.getView() 时重新创建 View ,而是修改 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;
}

如果这成功地解决了您的问题,则意味着之前在将播放器设置为 Activity 状态时,ListView 会再次获取所有 View 进行渲染、重新创建它们,并清除所有以前的状态。

关于java - Android:如何使用扩展布局类作为ListView行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25162458/

相关文章:

java - 改造 1.9 以使用 jhipster oauth 响应未填充

java - 替换ListView的 'column'中的数据

java - 在Appium(Android)中获取所有子笔记仅比父对象低一级

android - 如何正确处理 ListView 中的 Android EditText 输入?

java - 本地使用 Gradle 的 Sonar

java - getStringExtra() 为空时的默认值

java - SonarQube Java 分析器是否应该能够分析语义上不正确的 Java 源代码?

java - 方法中的对象和基元

android - 在 Delphi Firemonkey 移动应用程序中读写 inifile?

java - 在 RecyclerView Adapter 中显示 sharedpreference