0

I'm trying to get a value from an intent in my adapter within a bundle but it seems to give me a null pointer exception

I'm not sure, from what i can tell the get extra bundle is giving me a NPE, not sure how to fix it though //first the adapter public class ArticleAdapter extends RecyclerView.Adapter {

    class MyViewHolder extends RecyclerView.ViewHolder {
         TextView category;
        TextView title;
         ImageView image;
         TextView pubDate;

        MyViewHolder(View view) {
            super(view);
            title = (TextView) view.findViewById(R.id.row_title);
            image = (ImageView) view.findViewById(R.id.row_image);
            pubDate = (TextView) view.findViewById(R.id.row_pubDate);
            category = (TextView) view.findViewById(R.id.row_categories);
        }
    }
    @NotNull
    @Override
    public MyViewHolder onCreateViewHolder(@NotNull ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.row,parent, false);
        return new MyViewHolder(v);
    }


    private List<Article> articles;

    private Context mContext;
    private WebView articleView;

    public ArticleAdapter(List<Article> list, Context context) {
        this.articles = list;
        this.mContext = context;
    }

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


    @Override
    public void onBindViewHolder(@NonNull final MyViewHolder viewHolder, int position) {

        Article currentArticle = articles.get(position);
        Log.e("article", currentArticle.getTitle());
        String pubDateString;
        try {
            String sourceDateString = currentArticle.getPubDate();

            SimpleDateFormat sourceSdf = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z", Locale.ENGLISH);
            Date date = sourceSdf.parse(sourceDateString);

            SimpleDateFormat sdf = new SimpleDateFormat("dd MMMM yyyy", Locale.getDefault());
            pubDateString = sdf.format(date);

        } catch (ParseException e) {
            e.printStackTrace();
            pubDateString = currentArticle.getPubDate();
        }

        viewHolder.title.setText(currentArticle.getTitle());

        Picasso.get()
                .load(currentArticle.getImage())
                .placeholder(R.drawable.placeholder)
                .into(viewHolder.image);

        viewHolder.pubDate.setText(pubDateString);

        StringBuilder categories = new StringBuilder();
        for (int i = 0; i < currentArticle.getCategories().size(); i++) {
            if (i == currentArticle.getCategories().size() - 1) {
                categories.append(currentArticle.getCategories().get(i));
            } else {
                categories.append(currentArticle.getCategories().get(i)).append(", ");
            }
        }

        viewHolder.category.setText(categories.toString());

        viewHolder.itemView.setOnClickListener(new View.OnClickListener() {

            @SuppressLint("SetJavaScriptEnabled")
            @Override
            public void onClick(View view) {
                articleView = new WebView(mContext);

                articleView.getSettings().setLoadWithOverviewMode(true);

                String title = articles.get(viewHolder.getAdapterPosition()).getTitle();
                String content = articles.get(viewHolder.getAdapterPosition()).getContent();

                articleView.getSettings().setJavaScriptEnabled(true);
                articleView.setHorizontalScrollBarEnabled(false);
                articleView.setWebChromeClient(new WebChromeClient());
                articleView.loadDataWithBaseURL(null, "<style>img{display: inline; height: auto; max-width: 100%;} " +

                        "</style>\n" + "<style>iframe{ height: auto; width: auto;}" + "</style>\n" + content, null, "utf-8", null);

                Intent intent = new Intent(mContext,DetailActivity.class);
                intent.putExtra("setTitle",title);
                intent.putExtra("setContent",content);
                mContext.startActivity(intent);
            }
        });
    }

    @Override
    public int getItemCount() {
        return articles == null ? 0 : articles.size();
    }
}
//the Activity code
public class DetailActivity extends AppCompatActivity {

    DetailFragment mDetailFragment;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_detail);
        DetailFragment mDetailFragment = (DetailFragment)getSupportFragmentManager().findFragmentByTag("TAG");
        Intent intent = getIntent();
        Bundle bundle = intent.getExtras();
        mDetailFragment.setTitle((String) bundle.get("setTitle"));
        showDetailFragment();
    }

    private void startTransactionFragment(Fragment fragment) {
        if (!fragment.isVisible()) {
            getSupportFragmentManager().beginTransaction().add(R.id.detail_activity_frame_layout, fragment).commit();
        }
    }
    private void showDetailFragment() {
        if (this.mDetailFragment == null) this.mDetailFragment = DetailFragment.newInstance();
        this.startTransactionFragment(this.mDetailFragment);
    }
}
//the fragment code
public class DetailFragment extends Fragment {

    @BindView(R.id.detail_title) TextView title;
    @BindView(R.id.detail_content) WebView content;
    private WebView articleView;

    public DetailFragment() {   }

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


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

        ButterKnife.bind(this, view);
        return view;

    }
    public void setTitle(String s){ title.setText(s); }
    public void setContent(String s){
        articleView = new WebView(getContext());
        articleView.getSettings().setLoadWithOverviewMode(true);
        articleView.getSettings().setJavaScriptEnabled(true);
        articleView.setHorizontalScrollBarEnabled(false);
        articleView.setWebChromeClient(new WebChromeClient());
        articleView.loadDataWithBaseURL(null, "<style>img{display: inline; height: auto; max-width: 100%;} " +

                "</style>\n" + "<style>iframe{ height: auto; width: auto;}" + "</style>\n" + s, null, "utf-8", null);

    }

}
//and finally the xml code for both
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".Controllers.Fragments.DetailFragment"
    android:tag="TAG">
    <TextView
        android:id="@+id/detail_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="TITLE"
        android:textSize="50dp"/>
    <WebView
        android:id="@+id/detail_content"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="ARTICLE"
        android:textSize="20dp"
        android:layout_gravity="center"/>

</LinearLayout>
//activity xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/detail_activity_frame_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".Controllers.Activities.DetailActivity">

</FrameLayout>

updated stack trace:

E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.rssreader, PID: 25621 java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.rssreader/com.example.rssreader.Controllers.Activities.DetailActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.example.rssreader.Controllers.Fragments.DetailFragment.setTitle(java.lang.String)' on a null object reference at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2778) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856) at android.app.ActivityThread.-wrap11(Unknown Source:0) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:164) at android.app.ActivityThread.main(ActivityThread.java:6494) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807) Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void com.example.rssreader.Controllers.Fragments.DetailFragment.setTitle(java.lang.String)' on a null object reference at com.example.rssreader.Controllers.Activities.DetailActivity.onCreate(DetailActivity.java:28) at android.app.Activity.performCreate(Activity.java:7009) at android.app.Activity.performCreate(Activity.java:7000) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1214) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2731) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856)  at android.app.ActivityThread.-wrap11(Unknown Source:0)  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589)  at android.os.Handler.dispatchMessage(Handler.java:106)  at android.os.Looper.loop(Looper.java:164)  at android.app.ActivityThread.main(ActivityThread.java:6494)  at java.lang.reflect.Method.invoke(Native Method)  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807) 

1 Answers1

1

This happens because the mDetailFragment is not initialized.

The stack trace show that mDetailFragment = null

java.lang.NullPointerException: Attempt to invoke virtual method 'void com.example.rssreader.Controllers.Fragments.DetailFragment.setTitle(java.lang.String)' on a null

Basically what you need to do is this

// Let's first dynamically add a fragment into a frame container, that is your xml like a LinearLayout
         getSupportFragmentManager().beginTransaction(). 
             replace(R.id.YOUR_XML, new DetailFragment(), "SOMETAG").
             commit();
         // Now later we can lookup the fragment by tag
         DetailFragment mDetailFragment = (DetailFragment) 
             getSupportFragmentManager().findFragmentByTag("SOMETAG");

To use a Fragment there are a few ways showed here in this tutorial Creating and Using Fragments

UPDATE

Change your onCreate() to something like this:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_detail);
    Intent intent = getIntent();
    Bundle bundle = intent.getExtras();
    DetailFragment fragment = (DetailFragment)getSupportFragmentManager().findFragmentByTag("TAG");
    if(fragment == NULL){
        fragment = DetailFragment.newInstance();
    }
    fragment.setTitle((String) bundle.get("setTitle"));
    startTransactionFragment(fragment);
}

I have not tested the code, just from the top of my head..

Erik
  • 5,039
  • 10
  • 63
  • 119
  • I think i already did it before posting the question: //extract from detail activity private void startTransactionFragment(Fragment fragment) { if (!fragment.isVisible()) { getSupportFragmentManager().beginTransaction().add(R.id.detail_activity_frame_layout, fragment).commit(); } } private void showDetailFragment() { if (this.mDetailFragment == null) this.mDetailFragment = DetailFragment.newInstance(); this.startTransactionFragment(this.mDetailFragment); } – Aziz Boubaker Jun 03 '19 at 12:03
  • Even if you insert the DetailFragment into the FragmentManager does not make the mDetailFragment alive, you have to pull out the DetailFragment from the FragmentManager using like findFragmentBy... and then it will be not null – Erik Jun 03 '19 at 12:08
  • still doesn't work, same crash, same stack trace – Aziz Boubaker Jun 03 '19 at 12:17
  • Maybe read trough the "Creating and Using Fragments" link tutorial and you probable will be an expert on this – Erik Jun 03 '19 at 12:20
  • I did read that before, and no reading doesn't make me an expert, experience does, and thanks for the help, i appreciate it – Aziz Boubaker Jun 03 '19 at 12:23
  • you could show all your relevant code, that would probably give an answer to your question, full Activity and Fragment code, xml and adapter – Erik Jun 03 '19 at 12:28
  • i just updated the post with full code – Aziz Boubaker Jun 03 '19 at 12:55
  • I see what the problem is, updating my answer in a bit – Erik Jun 03 '19 at 13:42
  • still doesn't work, gives me the npe – Aziz Boubaker Jun 07 '19 at 09:21