簡體   English   中英

從活動中的片段上的數組列表中刪除項目

[英]Delete item from arraylist on Fragment from Activity

我正在嘗試通過創建一個可以刪除項目的簡單購物清單來立即了解如何在帶有活動的片段之間來回傳遞數據。 雜貨ArrayList將與刪除按鈕一起存在於Activity中,並且Fragment將顯示ArrayList。 當應用啟動並加載所有內容時,用戶將能夠從Fragment列表中選擇一個項目。 當用戶單擊Delete時,將刪除ArrayList中的選定項,並且Fragment將重新加載更新的列表。

我可以啟動該應用程序,並且一切正常加載,直到刪除一個項目為止。 該項目將刪除(我需要檢查日志),但是我需要找到一種方法來更新片段中的ArrayList。 當我嘗試再次刪除另一個項目時,應用程序崩潰。

這是我的日志:

java.lang.IllegalStateException: The content of the adapter has 
changed but ListView did not receive a notification. Make sure 
the content of your adapter is not modified from a background 
thread, but only from the UI thread. Make sure your adapter calls 
notifyDataSetChanged() when its content changes. [in ListView(2131427424,
class android.widget.ListView) with Adapter(class android.widget.ArrayAdapter)]

這是我的MainActivity:

public class MainActivity extends AppCompatActivity implements Tab1.OnDataPass {

public SectionsPageAdapater mSectionsPageAdapter;
ViewPager mViewPager;

ArrayList<String> valuesArray = new ArrayList<String>();

int index = -1;

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

    mSectionsPageAdapter = new SectionsPageAdapater(getSupportFragmentManager());
    mViewPager = (ViewPager) findViewById(R.id.viewContainer);

    valuesArray.add("apple");
    valuesArray.add("banana");
    valuesArray.add("cherry");
    valuesArray.add("dragon fruit");
    valuesArray.add("eggplant");

    mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
        }

        @Override
        public void onPageSelected(int position) {

        }

        @Override
        public void onPageScrollStateChanged(int state) {

        }
    });

    setupViewPager(mViewPager);
}

@Override
public void onDataPass(Integer indexNum) {
    index = indexNum;
}

public void onClickDelete (View v) {

    if (index >= 0) {
        valuesArray.remove(index);
    }

    index = -1;
}

private void setupViewPager(ViewPager viewPager) {
    SectionsPageAdapater adapter = new SectionsPageAdapater(getSupportFragmentManager());
    adapter.addFragment(new Tab1(), "TAB1");
    viewPager.setAdapter(adapter);
}

public ArrayList<String> getDataLog() {
    return valuesArray;
}
}

我的片段:

public class Tab1 extends Fragment {
Button btnPass, btnPass2;
ListView listview;
ArrayList<String> valuesArray = new ArrayList<String>();

int index = -1;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.activity_tab1,container,false);

    btnPass = view.findViewById(R.id.btnPass);
    btnPass2 = view.findViewById(R.id.btnPass2);

    listview = view.findViewById (R.id.listview);

    MainActivity activity = (MainActivity) getActivity();
    valuesArray = activity.getDataLog();


    ArrayAdapter<String> adapter = new ArrayAdapter<String>(getContext(),
            android.R.layout.simple_list_item_1, valuesArray);
    listview.setAdapter(adapter);

    listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> adapter, View view, int position, long id) {
            index = (int) id;
            passData((index));
        }
    });

    return view;
}



OnDataPass dataPasser;

public interface OnDataPass {
    void onDataPass(Integer index);
}

@Override
public void onAttach(Context a) {
    super.onAttach(a);
    dataPasser = (OnDataPass) a;
}

public void passData(Integer index) {
    dataPasser.onDataPass(index);
}
}

而我的適配器:

public class SectionsPageAdapater extends FragmentPagerAdapter {

private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();

public void addFragment(Fragment fragment, String title) {
    mFragmentList.add(fragment);
    mFragmentTitleList.add(title);
}

public SectionsPageAdapater(FragmentManager fm) {
    super(fm);
}

@Override
public CharSequence getPageTitle(int position) {
    return mFragmentTitleList.get(position);
}

@Override
public Fragment getItem(int position) {
    return mFragmentList.get(position);
}

@Override
public int getCount() {
    return mFragmentList.size();
}
}

在Android中,每個ListView對象都有一個相應的Adapter對象,該對象實際上保存數據並將View傳遞給ListView進行顯示。 需要注意的是, 每次適配器保存數據時,都必須顯式調用適配器的notifyDatasetChanged方法,以確保將更改通知給ListView對象並處理相應的UI更新。

因此,在您的情況下,您應該將ArrayAdapter對象存儲在Activity類中,並將其傳遞給Fragment而不是保存數據的實際ArrayList。 每當用戶按下刪除按鈕時,就會調用onClickDelete方法。 在該方法內部,對實際的ArrayList進行notifyDatasetChanged后,應調用適配器的notifyDatasetChanged方法。

設置您的“ Fragment / Activity關系,以便:

  • 調用passData ,您傳遞的是position而不是id值:

     public void onItemClick(AdapterView<?> adapter, View view, int position, long id) { passData(position); } /* Activity */ @Override public void onDataPass(int index) { this.indexToDelete = index; } 
  • 調用onClickDelete ,請刪除該元素,然后為ListView調用適配器上的notifyDataSetChanged() 為此,您可能需要引用您的Fragment (如果使用ViewPager,這比平時要難一些),或者您需要使用一些其他機制,例如EventBus。 在這里,您可以只存儲對Tab1的引用:

     //Instance variable Tab1 tab1; //... private void setupViewPager(ViewPager viewPager) { SectionsPageAdapater adapter = new SectionsPageAdapater(getSupportFragmentManager()); tab1 = new Tab1(); adapter.addFragment(tab1, "TAB1"); viewPager.setAdapter(adapter); } 

接着...

public void onClickDelete (View v) {
      if(indexToDelete < 0 || indexToDelete >= valuesArray.size()) {
          return; //invalid index
      }
      valuesArray.remove(indexToDelete);
      tab1.listView.getAdapter().notifyDataSetChanged();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM