klinker24 / Android-TextView-LinkBuilder

Insanely easy way to define clickable links within a TextView.
MIT License
1.59k stars 199 forks source link

Help: I couldn't use it #34

Closed ghost closed 8 years ago

ghost commented 8 years ago

Please I'm finding it difficult to use. Please can you help me out?

My Activity

    public class PostDetails extends AppCompatActivity {

    private final String TAG = "PostDetails";
    private AlertDialog internetDialog;
    private AlertDialog sthWrongAlert;

    private String postData;

    protected com.nostra13.universalimageloader.core.ImageLoader mImageLoader;

    TextView postTitle, postContent;
    private String post_content;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_post_details);

        showDialog();
        sthWrongDialog();

        postTitle = (TextView) findViewById(R.id.dpost_title);
        postContent = (TextView) findViewById(R.id.dpost_content);
        postContent.setMovementMethod(LinkMovementMethod.getInstance());

        Link link = new Link(Regex.WEB_URL_PATTERN)
                .setTextColor(Color.GREEN)
                .setHighlightAlpha(.4f)
                .setUnderlined(false)
                .setBold(true)
                .setOnClickListener(new Link.OnClickListener() {
                    @Override
                    public void onClick(String clickedText) {
                        Toast.makeText(PostDetails.this, "Link clicked is :: " + clickedText, Toast.LENGTH_SHORT).show();
                        finish();
                    }
                });

        LinkBuilder.on(postContent)
                .addLink(link)
                .build();

        DisplayImageOptions defaultoptions = new DisplayImageOptions.Builder()
                .cacheInMemory(true)
                .cacheOnDisk(true)
                .build();
        ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getApplicationContext())
                .defaultDisplayImageOptions(defaultoptions)
                .writeDebugLogs()
                .build();

        mImageLoader = com.nostra13.universalimageloader.core.ImageLoader.getInstance();
        mImageLoader.init(config);

        loadPost();
    }

    private void showDialog() {
        internetDialog = new AlertDialog.Builder(PostDetails.this)
               ...
    }

    private void sthWrongDialog() {
        sthWrongAlert = new AlertDialog.Builder(PostDetails.this)
               ...
    }

    private void loadPost() {
        Log.d(TAG, "loadPost called");

        final ProgressBar progressBar;
        progressBar = (ProgressBar) findViewById(R.id.progress_circle);
        progressBar.setVisibility(View.VISIBLE);

        String news_id = getIntent().getStringExtra("PostId");
        Log.d(TAG, "You clicked post id " + news_id);

        StringRequest stringRequest = new StringRequest(news_id,
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                        //Log.d("Debug", response.toString());
                        if (progressBar != null) {
                            progressBar.setVisibility(View.GONE);
                        }
                        parseHtml(response);
                        postData = response;
                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        VolleyLog.d(TAG, "Error: " + error.getMessage());

                        if (progressBar != null) {
                            progressBar.setVisibility(View.GONE);
                        }
                        sthWrongAlert.show();
                    }
                });

        //Creating requestqueue
        RequestQueue requestQueue = Volley.newRequestQueue(this);

        //Adding request queue
        requestQueue.add(stringRequest);
    }

    private void parseHtml(String response) {
        Log.d(TAG, "parsinghtml");
        Document document = Jsoup.parse(response);
        String post_title = document.select("h1.entry-title").first().text();
        post_content = document.select("div.entry-content").first().html();

        postTitle.setText(post_title);

        Spanned spanned = Html.fromHtml(post_content, new UILImageGetter(postContent, this), null );
        postContent.setText(spanned);

        //Unhiding views
        postTitle.setVisibility(View.VISIBLE);
        postContent.setVisibility(View.VISIBLE);
    }

    ...
}

When I click on a link, it's supposed to close this activity and show a toast but that ain't happening. Rather, clicking a link still fires the chooser to choose web browsers. Please, what am I getting wrong?

klinker24 commented 8 years ago

At the bottom, when you set the text on the TextView from the HTML, you are creating a new Span and overwriting the Span that you created with LinkBuiler.

To fix it, after you set the text, just build the link again. Link builder looks at the current text, it doesn't apply to text you place in your text view in the future.

ghost commented 8 years ago

I did this

    public class PostDetails extends AppCompatActivity {

    private final String TAG = "PostDetails";
    private AlertDialog internetDialog;
    private AlertDialog sthWrongAlert;
     private Link mLink;

    private String postData;

    protected com.nostra13.universalimageloader.core.ImageLoader mImageLoader;

    TextView postTitle, postContent;
    private String post_content;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_post_details);

        showDialog();
        sthWrongDialog();

        postTitle = (TextView) findViewById(R.id.dpost_title);
        postContent = (TextView) findViewById(R.id.dpost_content);
        postContent.setMovementMethod(LinkMovementMethod.getInstance());

       mLink = new Link(Regex.WEB_URL_PATTERN)
            .setTextColor(Color.GREEN)
            .setHighlightAlpha(.4f)
            .setUnderlined(false)
            .setBold(true)
            .setOnClickListener(new Link.OnClickListener() {
                @Override
                public void onClick(String clickedText) {
                    Toast.makeText(PostDetails.this, "Link clicked is :: " + clickedText, Toast.LENGTH_SHORT).show();
                    finish();
                }
            });

        DisplayImageOptions defaultoptions = new DisplayImageOptions.Builder()
                .cacheInMemory(true)
                .cacheOnDisk(true)
                .build();
        ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getApplicationContext())
                .defaultDisplayImageOptions(defaultoptions)
                .writeDebugLogs()
                .build();

        mImageLoader = com.nostra13.universalimageloader.core.ImageLoader.getInstance();
        mImageLoader.init(config);

        loadPost();
    }

    private void showDialog() {
        internetDialog = new AlertDialog.Builder(PostDetails.this)
               ...
    }

    private void sthWrongDialog() {
        sthWrongAlert = new AlertDialog.Builder(PostDetails.this)
               ...
    }

    private void loadPost() {
        Log.d(TAG, "loadPost called");

        final ProgressBar progressBar;
        progressBar = (ProgressBar) findViewById(R.id.progress_circle);
        progressBar.setVisibility(View.VISIBLE);

        String news_id = getIntent().getStringExtra("PostId");
        Log.d(TAG, "You clicked post id " + news_id);

        StringRequest stringRequest = new StringRequest(news_id,
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                        //Log.d("Debug", response.toString());
                        if (progressBar != null) {
                            progressBar.setVisibility(View.GONE);
                        }
                        parseHtml(response);
                        postData = response;
                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        VolleyLog.d(TAG, "Error: " + error.getMessage());

                        if (progressBar != null) {
                            progressBar.setVisibility(View.GONE);
                        }
                        sthWrongAlert.show();
                    }
                });

        //Creating requestqueue
        RequestQueue requestQueue = Volley.newRequestQueue(this);

        //Adding request queue
        requestQueue.add(stringRequest);
    }

    private void parseHtml(String response) {
        Log.d(TAG, "parsinghtml");
        Document document = Jsoup.parse(response);
        String post_title = document.select("h1.entry-title").first().text();
        post_content = document.select("div.entry-content").first().html();

        postTitle.setText(post_title);

        Spanned spanned = Html.fromHtml(post_content, new UILImageGetter(postContent, this), null );
        postContent.setText(spanned);

        LinkBuilder.on(postContent)
                .addLink(mLink)
                .build();

        //Unhiding views
        postTitle.setVisibility(View.VISIBLE);
        postContent.setVisibility(View.VISIBLE);
    }

    ...
}

but it still didn't work. Maybe I didn't understand your answer.

klinker24 commented 8 years ago

Without knowing the content within the HTML, i don't know what to look for.

I would imagine that it isn't finding any web links from your regular expression since the links are actually hidden in an href tag.

fromHTML is also basically doing the same thing as link builder does. It is redundant to do both that, and try to build a web link with my library.

ghost commented 8 years ago

So what do you advice I do?

klinker24 commented 8 years ago

Since all you are doing is opening web links, I would suggest creating your own LinkMovementMethod. This would allow you to redirect to a custom intent, rather than the chrome browser:

https://gist.github.com/zackehh/8676560

ghost commented 8 years ago

I still prefer your library since might include hashtags and numbers in the future.

However, I discovered that when I comment out

  Spanned spanned = Html.fromHtml(post_content, new UILImageGetter(postContent, this), null );

and set

    postContent.setText(post_content);

It works but the displayed text is not Html formatted. Is there anyway I can do Html.fromHtml () in the library so the displayed text will be properly formatted?

klinker24 commented 8 years ago

I think you should fork the project, add an example of what you are trying to do, then reopen the issue and tell me where I can find your fork. Then I will see if I can find what is going on.

ghost commented 8 years ago

The project is quite large but I'll lay down what I'm trying to do. I'm fetching blog posts from a blog. The posts contains links and images. I use UILImageGetter to load the images but the problem I'm having is the links. I want my activity to handle links that belongs to the blog while links that doesn't belong to the blog should fire a chooser for web browsers.

Do you get me now?

klinker24 commented 8 years ago

I really need you to fork my project and add a simple example. You do not have to include your entire project in the example, just make something to do what you have described. I want something to play with, not a description. That will help me solve it.

ghost commented 8 years ago

I have done as you requested Sir, this is the project

klinker24 commented 8 years ago

I really would have preferred you make a simple example using my project... That way I could have played with the library along with it, that is why I asked to fork my project. All we really needed was some code to download an article, then try to display it from Html.fromHtml().

This is fine though, I will see what I can do in the next few days.

ghost commented 8 years ago

Thanks, bro

klinker24 commented 8 years ago

This commit (https://github.com/klinker24/Android-TextView-LinkBuilder/commit/1b9ab9e3843f41114570ba2c468a4e6d82c91f9c) demonstrates LinkBuilder working just fine along with <a> tags within HTML text.

I honestly do not know what isn't working on your implementation, i have not looked deep enough. My guesses:

  1. your regular expression is bad
  2. the ImageGetter is messing something up
  3. You are overwriting the Span that LinkBuilder sets on your TextView
  4. You are overwriting the LinkMovementMethod at some point

This commit shows that the problem is in the implementation though, not the library. I would suggest a thorough check to ensure all of those 4 points are correct.

ghost commented 8 years ago

I really appreciate the length you went you to to help me. I believe I have thoroughly checked your example and I discovered that it works perfectly if you know the link text before hand.

Let's take this scenario: You have text that you fetch from the internet. The text contain random links in random positions. You don't know what goes between the a tags but the you know that it's have this format <a href="http://mywebsite/blah-lah">Some random text</a>.

Please, how can one apply LinkBuilder in such a scenario?

klinker24 commented 8 years ago

Oh, you cannot, that is not the way that link builder works at all...

On Mon, May 9, 2016, 7:41 PM ozuf notifications@github.com wrote:

I really appreciate the length you went you to to help me. I believe I have thoroughly checked your example and I discovered that it works perfectly if you know the link text before hand.

Let's take this scenario: You have text that you fetch from the internet. The text contain random links in random positions. You don't know what goes between the a tags but the you know that it's have this format Some random text.

Please, how can one apply LinkBuilder in such a scenario?

— You are receiving this because you modified the open/close state.

Reply to this email directly or view it on GitHub https://github.com/klinker24/Android-TextView-LinkBuilder/issues/34#issuecomment-218030012

ghost commented 8 years ago

Ok. Please, do you know how I can do that or any library that can?

klinker24 commented 8 years ago

You will have to make a custom LinkMovementMethod like I told you about before and make that use both the link builder one that I have made and the custom one like the link had.

On Mon, May 9, 2016, 8:02 PM ozuf notifications@github.com wrote:

Ok. Please, do you know how I can do that or any library that can?

— You are receiving this because you modified the open/close state.

Reply to this email directly or view it on GitHub https://github.com/klinker24/Android-TextView-LinkBuilder/issues/34#issuecomment-218032650

ghost commented 8 years ago

I used the custom LinkMovementMethod like you adviced but clicking the links is still firing up a chooser.

use both the link builder one that I have made and the custom one like the link had

Please could you expatiate on this?