如何将数据正确地从一项活动传递到另一项活动?

时间:2018-10-03 14:50:10

标签: java android webview parcelable

当前,我正在开发一个新闻应用程序,该应用程序已实现Webview,但URL并未加载数据并显示空白屏幕。我遵循了一些教程,其中可以使用Intents Parcelable传递对象。我想要实现的目的是,当用户单击文章项时,我想显示相应的URL,并使用Parcelable在Web视图中显示该视图,但显示白屏。

在我实施Webview的DetailActivity中的代码下方

public class DetailActivity extends Activity{
    @BindView(R.id.article)
    public WebView article_webview;



    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.detail_activity);
        ButterKnife.bind(this);
        Article object = (Article) getIntent().getParcelableExtra("myDataKey");
        article_webview.getSettings().setJavaScriptEnabled(true);
        article_webview.loadUrl("myDataKey");





    }
    public class WebViewController extends WebViewClient {

        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {

            return true;
        }
    }

**below my parcelable Model Article class **

public class Article implements Parcelable {

    @SerializedName("source")
    @Expose
    private Source source;
    @SerializedName("author")
    @Expose
    private String author;
    @SerializedName("title")
    @Expose
    private String title;
    @SerializedName("description")
    @Expose
    private String description;
    @SerializedName("url")
    @Expose
    private String url;
    @SerializedName("urlToImage")
    @Expose
    private String urlToImage;
    @SerializedName("publishedAt")
    @Expose
    private String publishedAt;
    @SerializedName("content")
    @Expose
    private String content;



    public Source getSource() {
        return source;
    }

    public void setSource(Source source) {
        this.source = source;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getUrlToImage() {
        return urlToImage;
    }

    public void setUrlToImage(String urlToImage) {
        this.urlToImage = urlToImage;
    }

    public String getPublishedAt() {
        return publishedAt;
    }

    public void setPublishedAt(String publishedAt) {
        this.publishedAt = publishedAt;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }






    public Article(Parcel in) {
        source = (Source) in.readValue(Source.class.getClassLoader());
        author = in.readString();
        title = in.readString();
        description = in.readString();
        url = in.readString();
        urlToImage = in.readString();
        publishedAt = in.readString();
        content = in.readString();
    }

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

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeValue(source);
        dest.writeString(author);
        dest.writeString(title);
        dest.writeString(description);
        dest.writeString(url);
        dest.writeString(urlToImage);
        dest.writeString(publishedAt);
        dest.writeString(content);
    }

    @SuppressWarnings("unused")
    public static final Parcelable.Creator<Article> CREATOR = new Parcelable.Creator<Article>() {
        @Override
        public Article createFromParcel(Parcel in) {
            return new Article(in);
        }

        @Override
        public Article[] newArray(int size) {
            return new Article[size];
        }
    };
}

在我要传递可包裹对象的MainActivity类下方

public class MainActivity extends BottomBarHolderActivity implements AllJazeeraFragment.OnFragmentInteractionListener, BBCFragment.OnFragmentInteractionListener, CNNFragment.OnFragmentInteractionListener, CBCNewsFragment.OnFragmentInteractionListener {


    //    private ApiService apiService;
    public static final String url_key = "urlKey";



    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
       // getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);

        Article article = new Article(Parcel.obtain());
        Intent i = new Intent(this, DetailActivity.class);


        i.putExtra("myDataKey", article.getUrl()); // using the (String name, Parcelable value) overload!
        startActivity(i);

        NavigationPage page1 = new NavigationPage("AllJazeera", ContextCompat.getDrawable(this, R.drawable.alljazeera), AllJazeeraFragment.newInstance());
        NavigationPage page2 = new NavigationPage("Support", ContextCompat.getDrawable(this, R.drawable.bbc_icon), CNNFragment.newInstance());
        NavigationPage page3 = new NavigationPage("Billing", ContextCompat.getDrawable(this, R.drawable.cnn_icon), AllJazeeraFragment.newInstance());
        NavigationPage page4 = new NavigationPage("Profile", ContextCompat.getDrawable(this, R.drawable.cbc_icon), CBCNewsFragment.newInstance());

        List<NavigationPage> navigationPages = new ArrayList<>();
        navigationPages.add(page1);
        navigationPages.add(page2);
        navigationPages.add(page3);
        navigationPages.add(page4);

        super.setupBottomBarHolderActivity(navigationPages);
    }


    public void onClicked() {
        Toast.makeText(this, "Clicked!", Toast.LENGTH_SHORT).show();
    }

}

在我的NewsAdapter类下面,在该类上我已对项目点击监听器和recyclerview进行了实现

public class NewsAdapter extends RecyclerView.Adapter<NewsAdapter.NewsViewHolder> {


    private List<Article> articleList;

    public NewsAdapter(List<Article> articleList) {

        this.articleList = articleList;
    }


    @NonNull
    @Override
    public NewsViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        View itemView = LayoutInflater.
                from(viewGroup.getContext()).
                inflate(R.layout.news_item, viewGroup, false);
        return new NewsViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(@NonNull NewsViewHolder newsViewHolder, int i) {
        Article article = articleList.get(i);
        newsViewHolder.articleAuthor.setText(article.getAuthor());
        newsViewHolder.articleTitle.setText(article.getTitle());
        newsViewHolder.articleDescription.setText(article.getDescription());
        Picasso.get().load(article.getUrlToImage()).into(newsViewHolder.articleImage);
        newsViewHolder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(view.getContext(), DetailActivity.class);
//start the activity from the view/context
                view.getContext().startActivity(intent);
            }
        });

    }





    @Override
    public int getItemCount() {

        return articleList.size();
    }


    public final static class NewsViewHolder extends RecyclerView.ViewHolder {
        // TextView articleAuthor, articleTitle, articleDescription, articleUrl;
        //  ImageView articleImage;

        @BindView(R.id.article_Image)
        ImageView articleImage;
        @BindView(R.id.article_Author)
        TextView articleAuthor;
        @BindView(R.id.article_Title)
        TextView articleTitle;

        @BindView(R.id.article_Description)
        TextView articleDescription;

        @BindView(R.id.article_Url)
        TextView articleUrl;


        public NewsViewHolder(View itemView) {
            super(itemView);
            ButterKnife.bind(this, itemView);


        }


    }
}

在我收到每个新闻的终点课程下

public interface NewsInterface {


    @GET("v2/top-headlines?sources=al-jazeera-english&apiKey=a5cc70bd52c9436785557878f4aa49e1")
    Call <ArticleResponse> getAllJazeera();

    @GET("v2/top-headlines?sources=cbc-news&apiKey=a5cc70bd52c9436785557878f4aa49e1")
    Call <ArticleResponse> getCbC();

    @GET("v2/top-headlines?sources=bbc-news&apiKey=a5cc70bd52c9436785557878f4aa49e1")
    Call <ArticleResponse> getBBC();

    @GET("v2/top-headlines?sources=cnn&apiKey=a5cc70bd52c9436785557878f4aa49e1")
    Call <ArticleResponse> getCNN();


}

在我的改造客户端类下

public class NewsClient  {

    public static final String BASE_URL = "https://newsapi.org/";

    /**
     * Get Retrofit Instance
     */
    private static Retrofit getRetrofitInstance() {
        return new Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .build();
    }

    /**
     * Get API Service
     *
     * @return API Service
     */
    public static NewsInterface getApiService() {
        return getRetrofitInstance().create(NewsInterface.class);
    }
    }


**below my CnnFragment class**
public class CNNFragment extends Fragment {


    private CNNFragment.OnFragmentInteractionListener listener;
    NewsAdapter adapter;
    public ArrayList<Article> articleList = new ArrayList();
    RecyclerView recyclerView;

    public static CNNFragment newInstance() {
        return new CNNFragment();
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        final View rootView = inflater.inflate(R.layout.cnn_fragment, container, false);
        NewsInterface apiService = NewsClient.getApiService();
        Call<ArticleResponse> call = apiService.getCNN();

        call.enqueue(new Callback <ArticleResponse>() {
            @Override
            public void onResponse(Call <ArticleResponse> call, Response <ArticleResponse> response) {

                articleList = new ArrayList(response.body().getArticles());
                recyclerView = (RecyclerView) rootView.findViewById(R.id.recycler_view);
                adapter = new NewsAdapter(articleList);
                RecyclerView.LayoutManager eLayoutManager = new LinearLayoutManager(getActivity());
                recyclerView.setLayoutManager(eLayoutManager);
                recyclerView.setAdapter(adapter);

            }

            @Override
            public void onFailure(Call <ArticleResponse> call, Throwable t) {

            }
        });

        return rootView;
    }


    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        if (context instanceof CNNFragment.OnFragmentInteractionListener) {
            listener = (CNNFragment.OnFragmentInteractionListener) context;
        } else {
            throw new RuntimeException(context.toString() + " must implement OnFragmentInteractionListener");
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
        listener = null;
    }

    public interface OnFragmentInteractionListener {
    }


}
我托管recyclerview的

和cnn_fragment.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:orientation="vertical"
    android:layout_height="match_parent">


    <android.support.v7.widget.RecyclerView
        android:layout_width="match_parent"
        android:id="@+id/recycler_view"
        android:scrollbars="vertical"
        android:layout_height="wrap_content"/>

</LinearLayout>

在实现了BBCNews的BBCFragment下方

公共类BBCFragment扩展了片段{

private OnFragmentInteractionListener listener;

RecyclerView recyclerView;
NewsAdapter adapter;
public ArrayList<Article> articleList = new ArrayList();
public static BBCFragment newInstance() {
    return new BBCFragment();
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
}

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

    NewsInterface apiService = NewsClient.getApiService();
    Call <ArticleResponse> call = apiService.getBBC();

    call.enqueue(new Callback <ArticleResponse>() {
        @Override
        public void onResponse(Call<ArticleResponse> call, Response <ArticleResponse> response) {

            articleList = new ArrayList(response.body().getArticles());
            recyclerView = (RecyclerView) rootView.findViewById(R.id.recycler_view);
            adapter = new NewsAdapter(articleList);
            RecyclerView.LayoutManager eLayoutManager = new LinearLayoutManager(getActivity());
            recyclerView.setLayoutManager(eLayoutManager);
            recyclerView.setAdapter(adapter);

        }

        @Override
        public void onFailure(Call<ArticleResponse> call, Throwable t) {

        }
    });

    return rootView;
}

@Override
public void onAttach(Context context) {
    super.onAttach(context);
    if (context instanceof OnFragmentInteractionListener) {
        listener = (OnFragmentInteractionListener) context;
    } else {
        throw new RuntimeException(context.toString() + " must implement OnFragmentInteractionListener");
    }
}

@Override
public void onDetach() {
    super.onDetach();
    listener = null;
}

public interface OnFragmentInteractionListener {
}

}

bbc_fragment.xml hosted recyclerview
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:orientation="vertical"
    android:layout_height="match_parent">


    <android.support.v7.widget.RecyclerView
        android:layout_width="match_parent"
        android:id="@+id/recycler_view"
        android:scrollbars="vertical"
        android:layout_height="wrap_content"/>

</LinearLayout>

其他片段新闻与以前的片段相同

在Pojo模型类别下

public class Article implements Parcelable {

    @SerializedName("source")
    @Expose
    private Source source;
    @SerializedName("author")
    @Expose
    private String author;
    @SerializedName("title")
    @Expose
    private String title;
    @SerializedName("description")
    @Expose
    private String description;
    @SerializedName("url")
    @Expose
    private String url;
    @SerializedName("urlToImage")
    @Expose
    private String urlToImage;
    @SerializedName("publishedAt")
    @Expose
    private String publishedAt;
    @SerializedName("content")
    @Expose
    private String content;



    public Source getSource() {
        return source;
    }

    public void setSource(Source source) {
        this.source = source;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getUrlToImage() {
        return urlToImage;
    }

    public void setUrlToImage(String urlToImage) {
        this.urlToImage = urlToImage;
    }

    public String getPublishedAt() {
        return publishedAt;
    }

    public void setPublishedAt(String publishedAt) {
        this.publishedAt = publishedAt;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }






    public Article(Parcel in) {
        source = (Source) in.readValue(Source.class.getClassLoader());
        author = in.readString();
        title = in.readString();
        description = in.readString();
        url = in.readString();
        urlToImage = in.readString();
        publishedAt = in.readString();
        content = in.readString();
    }

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

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeValue(source);
        dest.writeString(author);
        dest.writeString(title);
        dest.writeString(description);
        dest.writeString(url);
        dest.writeString(urlToImage);
        dest.writeString(publishedAt);
        dest.writeString(content);
    }

    @SuppressWarnings("unused")
    public static final Parcelable.Creator<Article> CREATOR = new Parcelable.Creator<Article>() {
        @Override
        public Article createFromParcel(Parcel in) {
            return new Article(in);
        }

        @Override
        public Article[] newArray(int size) {
            return new Article[size];
        }
    };
}

在文章响应类下方

公共类ArticleResponse {

@SerializedName("status")
@Expose
private String status;
@SerializedName("totalResults")
@Expose
private Integer totalResults;
@SerializedName("articles")
@Expose
private List<Article> articles = null;

public String getStatus() {
    return status;
}

public void setStatus(String status) {
    this.status = status;
}

public Integer getTotalResults() {
    return totalResults;
}

public void setTotalResults(Integer totalResults) {
    this.totalResults = totalResults;
}

public List<Article> getArticles() {
    return articles;
}

public void setArticles(List<Article> articles) {
    this.articles = articles;
}

}

在源模型类下方

public class Source {

    @SerializedName("id")
    @Expose
    private String id;
    @SerializedName("name")
    @Expose
    private String name;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

WorldNews课堂以下 公共类WorldNews {

@SerializedName("status")
@Expose
private String status;
@SerializedName("totalResults")
@Expose
private Integer totalResults;
@SerializedName("articles")
@Expose
private List<Article> articles = null;

public String getStatus() {
    return status;
}

public void setStatus(String status) {
    this.status = status;
}

public Integer getTotalResults() {
    return totalResults;
}

public void setTotalResults(Integer totalResults) {
    this.totalResults = totalResults;
}

public List<Article> getArticles() {
    return articles;
}

public void setArticles(List<Article> articles) {
    this.articles = articles;
}

}

3 个答案:

答案 0 :(得分:0)

您只是从MainActivity传递url(选中此行)

i.putExtra("myDataKey", article.getUrl());

因此,您将仅在下一类中获得url,而不是整个对象

请替换以下行,

Article object = (Article) getIntent().getParcelableExtra("myDataKey"); article_webview.getSettings().setJavaScriptEnabled(true);
article_webview.loadUrl("myDataKey");

与此:

String url = getIntent().getStringExtra("myDataKey");
 article_webview.getSettings().setJavaScriptEnabled(true);
article_webview.loadUrl(url);

答案 1 :(得分:0)

Article article = new Article(Parcel.obtain());

返回空的Article,因为Parcel.obtain()是空的Parcel。例如,创建一个Article

Article article = new Article(Parcel.obtain());
article.setUrl("https://google.com");

然后拨打电话

i.putExtra("myDataKey", article);

代替i.putExtra("myDataKey", article.getUrl());

onCreate()的{​​{1}}通话中

DetailActivity

更新:

@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.detail_activity); ButterKnife.bind(this); Article object = (Article) getIntent().getParcelableExtra("myDataKey"); article_webview.getSettings().setJavaScriptEnabled(true); article_webview.setWebViewClient(new WebViewClient()); article_webview.loadUrl(object.getUrl()); } 中删除startActivity(i)调用,并将此行添加到NewsAdapter的MainActivity回调中:

onClick()

这会将intent.putExtra("myDataKey", article); 传递给article

答案 2 :(得分:0)

请尝试“ getUrl()。toString”