【问题标题】:Live updating of ListView with ArrayAdapter使用 ArrayAdapter 实时更新 ListView
【发布时间】:2016-04-02 12:07:55
【问题描述】:

这里是 Android 初学者。

我有一个 MainActivity,它生成一个字符串并将其发送到一个 ArrayList(单例模式)。我还有一个 HistoryActivity,它将显示 ArrayList 的内容。

我将 ArrayList 发送到一个数组,并且 activity_history 在 HistoryActivity 中有一个带有 ArrayAdapter 的 ListView。 activity_history 上有一些按钮可以从 ArrayList 中删除一个项目(并重新创建 Array)并清除整个 ArrayList。但是,ListView 不会自动更新(必须关闭并重新打开活动)。

我目前正在尝试((BaseAdapter) historyView.getAdapter()).notifyDataSetChanged();(如下所示),但它不起作用。任何建议或指导都会很棒。

HistoryActivity.java

public class HistoryActivity extends AppCompatActivity {

DataStorage history = DataStorage.getDataStorage();
String[] historyArray;
private ListView historyView;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_history);
}

@Override
protected void onStart() {
    super.onStart();
    historyView = (ListView) findViewById(R.id.history);
    historyArray = history.getHistory().toArray(new String[history.getHistory().size()]);
    historyView.setAdapter(new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, historyArray));
}

/**
 * Clear all of history
 */
public void clearHist(View view) {
    history.getHistory().clear();
    historyArray = history.getHistory().toArray(new String[history.getHistory().size()]);
    ((BaseAdapter) historyView.getAdapter()).notifyDataSetChanged();
}

/**
 * Remove last entry to history
 */
public void clearOne(View view) {
    history.getHistory().remove(0);
    historyArray = history.getHistory().toArray(new String[history.getHistory().size()]);
    ((BaseAdapter) historyView.getAdapter()).notifyDataSetChanged();
}

/**
 * Change to main view
 */
public void sendMessage(View view) {
    Intent intent = new Intent(this, MainActivity.class);
    startActivity(intent);
}
}

activity_history.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#000000"

tools:context="com.mattbraddock.mbcgen.HistoryActivity">

<LinearLayout
    android:id="@+id/buttons"
    android:layout_width="match_parent"
    android:layout_height="60dp"
    android:layout_alignParentBottom="true">

    <Button
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:onClick="clearOne"
        android:text="Remove Last" />

    <Button
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:onClick="sendMessage"
        android:text="Return" />

    <Button
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:onClick="clearHist"
        android:text="Clear All" />

</LinearLayout>

<ListView
    android:id="@+id/history"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_above="@id/buttons"
    android:layout_alignParentTop="true"
    android:paddingBottom="16dp" />

</RelativeLayout>

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mattbraddock.mbcgen">

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity android:name=".MainActivity"
        android:screenOrientation="portrait"
        android:theme="@style/Theme.AppCompat.NoActionBar">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <activity android:name=".HistoryActivity"
        android:label="Card History"
        android:theme="@style/Theme.AppCompat.Dialog"
        android:screenOrientation="portrait"></activity>
    <!-- ATTENTION: This was auto-generated to add Google Play services to your project for
         App Indexing.  See https://g.co/AppIndexing/AndroidStudio for more information. -->
    <meta-data
        android:name="com.google.android.gms.version"
        android:value="@integer/google_play_services_version" />
</application>

</manifest>

【问题讨论】:

  • ArrayAdapter 接受一个 Arraylist... 为什么要坚持使用一个数组?另外,调用 notifyDatasetChanged 时不需要转换适配器
  • ArrayAdapter mAdapter = new ArrayAdapter&lt;&gt;(this, android.R.layout.simple_list_item_1, historyArray) 首先获取阵列适配器的引用。那就试试mAdapter.notifyDataSetChanged()
  • @cricket_007 - 如果我不转换适配器,我会在 notifyDataSetChanged() 上收到“无法解析方法”。
  • 我明白了。好吧,保存适配器是个好主意,那么

标签: java android listview arraylist


【解决方案1】:

问题是每次使用

historyArray = history.getHistory().toArray(new String[history.getHistory().size()]);

您将historyArray 变量的引用更改为另一个新创建的数组,但适配器仍保留对您传递给适配器构造函数的旧数组的引用。

我的建议是用ArrayList 替换您的数组并使用clear()add()addAll() 方法。如果您想保留对适配器数据的引用并让notifyDataSetChanged() 正常工作,也请避免重新分配historyArray

【讨论】:

  • 只需使用我的 ArrayList 而不是创建 Array 就足以解决问题。谢谢。
【解决方案2】:

我会保存对适配器的引用并使用 Arraylist 而不是数组。

historyView = (ListView) findViewById(R.id.history);
adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, history.getHistory());
historyView.setAdapter(adapter);

然后当你想更新视图时,只需修改适配器即可。

adapter.clear();

或者

adapter.remove(0);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多