繁体   English   中英

如何使用 Android 中 FirstActivity 的数据填充 SecondActivity 上的 ListView?

[英]How can I populate a ListView on a SecondActivity with data from FirstActivity in Android?

我正在开发一个图书搜索应用程序项目。 用户输入一个标题,应用程序会在 Google 图书中搜索它。
我最初有一个活动和布局。 我决定使用两种布局(一种供用户输入标题,另一种显示结果); 必须创建另一个活动,因为结果布局引发了关于“空”object 参考的异常。
创建第二个活动后,我使用意图在两个活动之间传输列表数据; 我很快就发现我必须为此目的使用SerializeParcelable object。
Following instructions at Pass list of objects from one activity to other activity in android & https://www.vogella.com/tutorials/AndroidParcelable/article.html , I failed at implementing both, because Serialize sent an empty ArrayList (thus, an空结果页面,即使有书籍点击)并且Parcelable 每次我使用它时都会抛出不同的异常,可能是因为我使用 ArrayAdapter 用书籍填充 ListView。
我认为我还没有准备好在https://www.vogella.com/tutorials/AutoValue/article.htmlments上实现 API。 更好的结构是使用单个活动, View.GONE我非常珍惜的背景图像,并在搜索字段下显示书籍对象列表。 但是最好对 Serialize & Parcelable 进行跟进——以用于未来的项目。 那么,各位开发者,有什么办法解决这个问题呢?

第一活动截图第二活动截图

这是我的代码: MainActivity:

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();
    }

}

第二活动:

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 .. 但是不建议用于高级代码库,但对于您的结构,您可以实现它。

只需在FirstActivity中声明一个像上面protected void onCreate()这样的变量 ..

public static List<Book> book_data = new ArrayList<>();

并将datapublic 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()));也可以尝试调试它

并在SecondActivity

@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

    ....
    ....
}

好的,所以我能够更正Parcelable接口的实现,现在FirstActivity将数据传递给SecondActivity 就是这个:

package project.android.gbookslisting;

import android.os.Parcel;
import android.os.Parcelable;

public class Book implements Parcelable {

    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(Parcel in) {
        this.book_title = in.readString();
        this.author = in.readString();
        this.publishing_year = in.readString();
        this.page = 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];
        }
    };

    protected String getAuthor () { return author; }

    protected String getPublishing_year () { return publishing_year; }

    protected String getPage () {
        return page;
    }

    protected String getBook_title () {
        return book_title;
    }

    @Override
    public int describeContents () {
        return 0;
    }

    @Override
    public void writeToParcel (Parcel parcel, int flags) {
        parcel.writeString(book_title);
        parcel.writeString(author);
        parcel.writeString(publishing_year);
        parcel.writeString(page);
    }

}

我在 GitHub @ GBooks Listing上共享了存储库,等待更多功能/更新。

ResultsActivity当然看起来很蹩脚,但我会改进主题和任何影响外观的东西。 谢谢。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM