我正在开发一个图书搜索应用程序项目。用户输入标题,应用程序会在 Google 图书中搜索该标题。
我最初只有一项 Activity 和布局。我决定使用两种布局(一种用于用户输入标题,另一种显示结果);必须创建另一个 Activity ,因为结果布局抛出有关“null”对象引用的异常。
创建第二个 Activity 后,我使用 Intent 在两个 Activity 之间传输列表数据;我很快就发现我必须使用Serialize或Parcelable对象来达到目的。
按照 Pass list of objects from one activity to other activity in android 的说明进行操作& https://www.vogella.com/tutorials/AndroidParcelable/article.html ,我都未能实现这两者,因为 Serialize 发送了一个空的 ArrayList(因此,一个空的结果页面,即使有图书命中) 和 Parcelable 每次我使用它时都会抛出不同的异常,可能是因为我使用 ArrayAdapter 用书籍填充 ListView。
我认为我还没有准备好在 https://www.vogella.com/tutorials/AutoValue/article.html 实现 API并且也不能使用 Fragment。更好的结构是使用单个 Activity ,View.GONE
我非常珍惜的背景图像,并在搜索字段下显示图书对象列表。但对于 future 的项目来说,对 Serialize & Parcelable 进行后续处理是件好事。
那么各位开发者,有什么解决办法吗?
FirstActivity screenshot SecondActivity screeenshot
这是我的代码: 主要 Activity :
package project.android.gbookslisting;
import android.app.LoaderManager;
import android.content.Intent;
import android.content.Loader;
import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import androidx.appcompat.app.AppCompatActivity;
import static project.android.gbookslisting.ResultsActivity.adapter;
//import android.support.v4.content.AsyncTaskLoader;
//import android.support.v7.app.AppCompatActivity;
public class ParamsActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<List<Book>>, Serializable {
private static final int LOADER_ID = 0;
private static String LOG_TAG = ParamsActivity.class.getName();
EditText text;
String query;
private LoaderManager loaderManager = getLoaderManager();
@Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.parameters);
Button query = findViewById(R.id.search_button);
text = findViewById(R.id.deets_field);
query.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick (View view) {
if (text.getText().toString().length() > 0) { loaderManager.initLoader(LOADER_ID, null, ParamsActivity.this);
} else if (text.getText().length() < 1) {
text.setHint("Please enter book title/details");
text.setHintTextColor(Color.RED);
}
}
});
}
@Override
public Loader<List<Book>> onCreateLoader (int i, Bundle bundle) {
query = text.getText().toString();
return new BookLoader(this, query);
}
@Override
public void onLoadFinished (Loader<List<Book>> loader, List<Book> data) {
// If there is a valid list of {@link Book}s, then add them to the adapter's dataset. This will trigger the ListView to update.
if (data != null && !data.isEmpty()) {
data = new ArrayList<Book>();
Intent i = new Intent(getApplicationContext(), ResultsActivity.class);
i.putExtra("data", (Serializable) data);
startActivity(i);
}
}
@Override
public void onLoaderReset (Loader loader) {
adapter = new Adapt(this, new ArrayList<Book>());
adapter.clear();
}
}
第二个 Activity :
package project.android.gbookslisting;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.TextView;
import java.io.Serializable;
import java.util.ArrayList;
import androidx.appcompat.app.AppCompatActivity;
public class ResultsActivity extends AppCompatActivity implements Serializable {
static Adapt adapter;
static TextView emptyResult;
ListView bookEntries;
String LOG_TAG = ResultsActivity.class.getName();
@Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.hits_page);
Intent i = getIntent();
ArrayList<Book> books = (ArrayList<Book>) i.getSerializableExtra("data");
emptyResult = findViewById(R.id.matches_nill);
emptyResult.setText(R.string.matches0);
if (!books.isEmpty()) {
emptyResult.setVisibility(View.GONE);
// Create a new adapter that takes a rich (or otherwise empty) list of books as input
adapter = new Adapt(this, new ArrayList<Book>());
// Get the list of books from {@link Search}
bookEntries = findViewById(R.id.catalog);
bookEntries.setAdapter(adapter);
bookEntries.setEmptyView(emptyResult);
bookEntries.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick (AdapterView<?> adapterView, View view, int position, long l) {
// Find the current book that was clicked on
Book currentBook = adapter.getItem(position);
// Convert the String URL into a URI object (to pass into the Intent constructor)
Uri bookUri = Uri.parse(currentBook.getPage());
// Create a new intent to view the book URI
Intent websiteIntent = new Intent(Intent.ACTION_VIEW, bookUri);
// Send the intent to launch a new activity
startActivity(websiteIntent);
}
});
// adapter.clear();
adapter.addAll(books);
} else {
emptyResult.setVisibility(View.VISIBLE);
emptyResult.setText(R.string.matches0);
}
}
}
图书对象:
package project.android.gbookslisting;
import java.io.Serializable;
import java.util.Date;
public class Book {
private String book_title;
private String author;
private String publishing_year;
private String page;
public Book (String theTitle, String theAuthor, String theYear, String thePage) {
this.book_title = theTitle;
this.author = theAuthor;
this.publishing_year = theYear;
this.page = thePage;
}
public Book setBook_title (String book_title) {
this.book_title = book_title;
return this;
}
public Book setAuthor (String author) {
this.author = author;
return this;
}
public Book setPublishing_year (String publishing_year) {
this.publishing_year = publishing_year;
return this;
}
public Book setPage (String page) {
this.page = page;
return this;
}
protected String getAuthor () {
return author;
}
protected String getPublishing_year () { return publishing_year; }
protected String getPage () {
return page;
}
protected String getBook_title () {
return book_title;
}
}
最佳答案
您可以声明一个变量来处理您的 data = new ArrayList<Book>();
如public static
..但是不建议将其用于高级代码库,但对于您的结构,您可以实现它。
只需声明一个像上面这样的变量 protected void onCreate()
在 FirstActivity ..
public static List<Book> book_data = new ArrayList<>();
并转移data
来自public void onLoadFinished (Loader<List<Book>> loader, List<Book> data)
至book_data
@Override
public void onLoadFinished (Loader<List<Book>> loader, List<Book> data) {
// If there is a valid list of {@link Book}s, then add them to the adapter's dataset. This will trigger the ListView to update.
if (data != null && !data.isEmpty()) {
//data = new ArrayList<Book>();
book_data = data;
Intent i = new Intent(getApplicationContext(), ResultsActivity.class);
startActivity(i);
}
}`
如果它包含值,您也可以尝试调试它
Log.d(TAG, String.valueOf(data.size()));
和第二个 Activity
@Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.hits_page);
List<Book> books = new ArrayList<>();
books = FirstActivity.book_data; //Get the data from the First Activity
....
....
}
关于java - 如何使用 Android 中 FirstActivity 的数据填充 SecondActivity 上的 ListView?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62032205/