2016-04-02 5 views
0

Начинает с Android здесь.Живое обновление ListView с ArrayAdapter

У меня есть MainActivity, которая генерирует String и отправляет ее в ArrayList (singleton pattern). У меня также есть HistoryActivity, который отобразит содержимое ArrayList.

У меня есть ArrayList, отправляемый в массив, и у Activity_history есть ListView с ArrayAdapter в HistoryActivity. В Activity_history есть кнопки, которые удаляют элемент из ArrayList (и воссоздают массив) и очищают весь массив 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> 
+0

ArrayAdapter принимает Список_массивов ... Почему вы настаиваете на использовании массива? Кроме того, вам не нужно отбрасывать адаптер при вызове notifyDatasetChanged –

+0

'ArrayAdapter mAdapter = new ArrayAdapter <> (это, android.R.layout.simple_list_item_1, historyArray)' сначала берет ссылку на адаптер массива. Затем попробуйте 'mAdapter.notifyDataSetChanged()' –

+0

@ cricket_007 - если я не использую адаптер, я получаю «Не могу разрешить метод» на 'notifyDataSetChanged()'. –

ответ

0

Проблема заключается в том, что каждый раз, когда вы используете

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

изменить ссылку переменной historyArray другому вновь созданного массива, но адаптер все еще содержит ссылку на старый массив, который вы передали в конструктор адаптера.

Мое предложение было бы заменить вам массив с ArrayList и использовать clear(), add() и addAll() методы. Также избегайте переназначения historyArray, если вы хотите сохранить ссылку на данные адаптера, а для notifyDataSetChanged() - работать.

+0

Просто для того, чтобы решить проблему, достаточно использовать мой ArrayList, а не создавать массив. Спасибо. –

0

Я бы сохранил ссылку на адаптер и использовал 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);