1

I have an activity with multiple tabs and each tab consists of a fragment with some text inside. I would like to have a text with "Read More" which is a link to an URL. Without having the link, everything works fine, but when I try to implement it, I get

E/UncaughtException: java.lang.NullPointerException

So I assume it is the way I implement it. Right now, the fragment has this:

public class About_us extends Fragment {

  public View onCreateView(LayoutInflater inflater, ViewGroup container,
    Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.fragment_about_us, container, false);
    //The part below is For Read More
    TextView t2 = (TextView) getView().findViewById(R.id.read_more);
    if (t2 != null) {
      t2.setMovementMethod(LinkMovementMethod.getInstance());
    }

    return rootView;
  }
}

"read_more" layout has this for the TextView:

< TextView
android: id = "@+id/read_more"
android: layout_width = "match_parent"
android: layout_height = "wrap_content"
android: clickable = "true"
android: text = "@string/link_to_the_website"
android: textColor = "@color/buttonColorPressed" / >

And link_to_website is given in the strings:

< string name = "link_to_the_website" > < a href = "www.google.com/" > Read More Here < /a></string >

Can anyone help me to figure out what is it that I wrote wrong?

CuriousPaul
  • 449
  • 8
  • 20

3 Answers3

2

Ether use your inflated view as

TextView t2 = (TextView) rootView.findViewById(R.id.read_more); 

or override onViewCreated and then you can use getView() or directed passed view

@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    TextView t2 = (TextView) view.findViewById(R.id.read_more);
    // or TextView t2 = (TextView) getView().findViewById(R.id.read_more);
}

Because getview will only return the actual view which was previously created and returned by onCreateView otherwise it will return null, hence the issue

getView()

Get the root view for the fragment's layout (the one returned by onCreateView(LayoutInflater, ViewGroup, Bundle)), if provided.

so you cannot use getView before the completion of onCreateView. Then with this approach, you split the task into two parts

onCreateView : for view inflation

onViewCreated: for view and listeners initialization

update : to add links

t2.setMovementMethod(LinkMovementMethod.getInstance());
t2.setText(Html.fromHtml("< string name = 'link_to_the_website' > < a href = 'https://www.google.com/' > Read More Here < /a></string >"));
Pavneet_Singh
  • 36,884
  • 5
  • 53
  • 68
  • Thank you for the nice and detailed answer. I have tried with TextView t2 = (TextView) rootView.findViewById(R.id.read_more); and nothing happens. Please see the comment above. If I can't solve it this way, I will try it in another way – CuriousPaul Jan 15 '18 at 14:16
  • @CuriousPaul don't try the other way, won't change anything , i will update the answer for linking part – Pavneet_Singh Jan 15 '18 at 14:19
  • Thank you for staying with me on this problem. The good news is that the link works and opens the browser, which is great. The problem is that instead of Read More Here, it shows the whole line "< string name = 'link_to_the_website' > < a href = 'https://www.google.com/' > Read More Here < /a>"), but with google.com highlighted. Is there something else I need to do? – CuriousPaul Jan 15 '18 at 14:44
  • @CuriousPaul try removing the `< string ...> ` pair, use `< a href = 'https://www.google.com' > Read More Here < /a>` – Pavneet_Singh Jan 15 '18 at 14:49
  • Did that. Now it shows underlined "Read More Here" as it should, but it doesn't do anything. This is what I have now: `t2.setText(Html.fromHtml(" Read More Here "));` I imported also import android.text.Html; – CuriousPaul Jan 15 '18 at 14:54
  • No reaction whatsoever. I also removed `android:autoLink="web"` and `android:text` from the Layout. What else can I do? – CuriousPaul Jan 15 '18 at 15:22
  • @CuriousPaul it should be `t2.setText(Html.fromHtml(" Read More Here "));` – Pavneet_Singh Jan 15 '18 at 15:22
  • I even tried like this ` t2.setText(Html.fromHtml("Visit W3Schools"));`, using the lesson from https://www.w3schools.com/tags/att_a_href.asp. No reaction – CuriousPaul Jan 15 '18 at 15:24
  • try adding `t2.setClickable(true);` – Pavneet_Singh Jan 15 '18 at 15:30
1

try to change the line in your code

TextView t2 = (TextView) rootView.findViewById(R.id.read_more);

and add the property in your xml in textview

android:autoLink="web" 
Sunil Soni
  • 443
  • 3
  • 18
  • Thank you! This part: TextView t2 = (TextView) rootView.findViewById(R.id.read_more); solved the crashing problem, but adding autoLink actually kills the link. However, if I remove "web" it says "No apps can perform this action" when clicking – CuriousPaul Jan 15 '18 at 14:15
0
// declare interface in fragment   
 public interface OnTextSelectedListener
  {
   void ontextSelected(String url);
  }

  @Override
  public void onAttach(Activity activity) {
      super.onAttach(activity);

    // This makes sure that the container activity has implemented
    // the callback interface. If not, it throws an exception
    try {
        mCallback = (OnTextSelectedListener) activity;
    } catch (ClassCastException e) {
        throw new ClassCastException(activity.toString()
                + " must implement OnTextSelectedListener");
    }
}

// Implement interface in activity


   public void ontextSelected(String   url) {
  // load your webview
   }

Check this link to understand fragment communication better.

Justcurious
  • 2,201
  • 1
  • 21
  • 36
  • Thank you! Would this go after onCreateView? And should I keep the layout and the strings code the same? – CuriousPaul Jan 15 '18 at 14:18
  • onCreateView Call listner method and for better understanding read fragment communication. Accept my answer if it helped you.@CuriousPaul – Justcurious Jan 15 '18 at 14:27