【问题标题】:Not able to send an Arraylist of objects using putparcelablearraylist to the fragment through bundle?无法使用 putparcelablearraylist 通过捆绑将对象的 Arraylist 发送到片段?
【发布时间】:2019-04-09 02:34:24
【问题描述】:

我一直在尝试使用 putparcelablearraylist 将对象的 Arraylist 通过捆绑发送到片段。但是我将 savedinstancestate 的值设为 null,因此我无法检索列表值。我的实现有什么问题吗??

Bundle 获取了参数,但是当我尝试接收片段中的对象数组列表时,我将保存的实例状态的值设为 null。

以下是我的 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();


}
}

【问题讨论】:

    标签: java android android-fragments parcelable


    【解决方案1】:

    发件人类

    Bundle bundle = new Bundle();
    bundle.putSerializable("bookarray",(ArrayList<Book>)b);
    

    接收器类

    book_a = (ArrayList<Book>)getArguments().getSerializable("bookarray");
    

    【讨论】:

    • 发布堆栈跟踪
    【解决方案2】:

    您正在添加捆绑包,然后设置 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();
    }
    

    在访问 saveInstanceState 之前,您还应该始终检查 null。

    @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:尝试在edu.temple的空对象引用上调用虚拟方法'java.util.ArrayList android.os.Bundle.getParcelableArrayList(java.lang.String)'。 edu.temple.assign8_latest.MainActivity.onCreate(MainActivity.java:35) 上的assign8_latest.FragmentA.onCreateView(FragmentA.java:37)
    • 我也有同样的异常 - NullPointer
    • @NagasaisashankKakarla 我已经编辑了我的答案,并提出了一些希望对您有所帮助的想法。
    猜你喜欢
    • 2011-05-14
    • 1970-01-01
    • 2017-05-27
    • 2013-04-15
    • 2015-09-14
    • 1970-01-01
    • 1970-01-01
    • 2018-05-23
    • 1970-01-01
    相关资源
    最近更新 更多