Я пытался отправить Arraylist объектов, используя putparcelablearraylist во фрагмент через пакет. Но я получаю значение saveinstancestate как нулевое и, следовательно, не могу получить значения списка. Что-то не так с моей реализацией??
Bundle принимает параметры, но когда я пытаюсь получить массив объектов во фрагменте, я получаю значение состояния сохраненного экземпляра как нулевое.
Ниже приведен код для моей MainActivity: -
public class MainActivity extends AppCompatActivity implements FragmentA.Communicator{
FragmentA f1;
FragmentB f2;
ArrayList<Book> b = new ArrayList<Book>(7);
FragmentManager manager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getBooks();
manager = getSupportFragmentManager();
f1 = (FragmentA) manager.findFragmentById(R.id.fragment);
f1.setCommunicator(this);
}
@Override
public void respond(int index) {
f2 = (FragmentB) manager.findFragmentById(R.id.fragment2);
if (f2!=null && f2.isVisible())
{
f2.changeData(index);
}
else
{
Bundle bundle = new Bundle();
bundle.putInt("index", index);
Fragment newFragment = new FragmentC();
newFragment.setArguments(bundle);
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.fragment, newFragment);
transaction.addToBackStack(null);
transaction.commit();
}
}
public void afterGetBooks(ArrayList<Book> bks) {
for (Book h : bks) {
b.add(h);
}
manager = getSupportFragmentManager();
Bundle bundle = new Bundle();
bundle.putParcelableArrayList("bookarray",(ArrayList<Book>)b);
f1.setArguments(bundle);
f1 = (FragmentA) manager.findFragmentById(R.id.fragment);
f1.setCommunicator(this);
}
private void getBooks(){
String url = Book.API.BASE_URL;
//ArrayList<Book> boo;
Retrofit retrofit = new Retrofit.Builder().baseUrl(Book.API.BASE_URL).addConverterFactory(GsonConverterFactory.create()).build();
Book.API api = retrofit.create(Book.API.class);
Call<ArrayList<Book>> call = api.getBooks();
call.enqueue(new Callback<ArrayList<Book>>() {
@Override
public void onResponse(Call<ArrayList<Book>> call, Response<ArrayList<Book>> response) {
ArrayList<Book> Books = response.body();
for(Book h: Books){
Log.d("Title",h.getTitle());
//b.add(h);
}
afterGetBooks(Books);
}
@Override
public void onFailure(Call<ArrayList<Book>> call, Throwable t) {
Toast.makeText(getApplicationContext(),t.getMessage(),Toast.LENGTH_SHORT).show();
}
});
}
}
Ниже приведен код для принимающего фрагмента:
public class FragmentA extends Fragment implements AdapterView.OnItemClickListener{
ListView list;
Communicator communicator;
ArrayList<Book> book_a;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view= inflater.inflate(R.layout.fragment_a,container,false);
savedInstanceState = getArguments();
book_a = savedInstanceState.getParcelableArrayList("bookarray");
Log.d("Frag_a:Title",book_a.get(5).getTitle());
list= (ListView) view.findViewById(R.id.listview);
ArrayAdapter adapter = ArrayAdapter.createFromResource(getActivity(),R.array.chapters,android.R.layout.simple_list_item_1);
list.setAdapter(adapter);
list.setOnItemClickListener(this);
return view;
}
public void setCommunicator(Communicator communicator)
{
this.communicator = communicator;
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
communicator.respond(position);
}
public interface Communicator{
public void respond(int index);
}
}
Ниже приведен код для пользовательского объекта:
public class Book implements Parcelable{
String title,author,coverURL;
int id, published;
public Book(String title, String author, String coverURL, int id, int published) {
this.id = id;
this.title = title;
this.author = author;
this.published = published;
this.coverURL = coverURL;
}
protected Book(Parcel in) {
id = in.readInt();
title = in.readString();
author = in.readString();
published = in.readInt();
coverURL = in.readString();
}
public static final Creator<Book> CREATOR = new Creator<Book>() {
@Override
public Book createFromParcel(Parcel in) {
return new Book(in);
}
@Override
public Book[] newArray(int size) {
return new Book[size];
}
};
public String getTitle() {
return title;
}
public String getAuthor() {
return author;
}
public String getCoverURL() {
return coverURL;
}
public int getId() {
return id;
}
public int getPublished() {
return published;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(id);
dest.writeString(title);
dest.writeString(author);
dest.writeInt(published);
dest.writeString(coverURL);
}
public interface API{
String BASE_URL = "https://kamorris.com/lab/audlib/";
@GET("booksearch.php")
Call<ArrayList<Book>> getBooks();
}
}
Класс отправителя
Bundle bundle = new Bundle();
bundle.putSerializable("bookarray",(ArrayList<Book>)b);
Класс приемника
book_a = (ArrayList<Book>)getArguments().getSerializable("bookarray");
Вы добавляете пакет, а затем устанавливаете f1. Попробуйте так.
public void afterGetBooks(ArrayList<Book> bks) {
for (Book h : bks) {
b.add(h);
}
manager = getSupportFragmentManager();
Bundle bundle = new Bundle();
bundle.putParcelableArrayList("bookarray",(ArrayList<Book>)b);
f1 = (FragmentA) manager.findFragmentById(R.id.fragment);
f1.setArguments(bundle);
f1.setCommunicator(this);
}
Также вы создаете фрагмент в двух местах. Вы должны создавать его только после того, как ваш массив будет заполнен.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getBooks();
}
Вы также должны всегда проверять значение null перед доступом к saveInstanceState.
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view= inflater.inflate(R.layout.fragment_a,container,false);
if (savedInstanceState != null) {
savedInstanceState = getArguments();
book_a = savedInstanceState.getParcelableArrayList("bookarray");
Log.d("Frag_a:Title",book_a.get(5).getTitle());
list= (ListView) view.findViewById(R.id.listview);
} else {
// do something else if the saved instance is null
}
ArrayAdapter adapter = ArrayAdapter.createFromResource(getActivity(),R.array.chapters,android.R.layout.simple_list_item_1);
list.setAdapter(adapter);
list.setOnItemClickListener(this);
return view;
}
Вызвано: android.view.InflateException: строка двоичного файла XML № 10: строка двоичного файла XML № 10: ошибка раздувания фрагмента класса Вызвано: android.view.InflateException: строка двоичного файла XML № 10: ошибка раздувания фрагмента класса Вызвано: java.lang.NullPointerException: попытка вызвать виртуальный метод java.util.ArrayList android.os.Bundle.getParcelableArrayList(java.lang.String) для нулевой ссылки на объект в edu.temple.assign8_latest.FragmentA.onCreateView(FragmentA. java:37) в edu.temple.assign8_latest.MainActivity.onCreate(MainActivity.java:35)
У меня такое же исключение - NullPointer
@NagasaisashankKakarla Я отредактировал свой ответ, добавив несколько, надеюсь, полезных идей.
трассировка стека сообщений