click link in textview - android

I have text view and I want to set-text as link to direct the site but
the problem is that I cannot click:
Grades = (TextView) findViewById(R.id.textView9);
Grades.setText(Html.fromHtml(course.getString(TAG_Grade)));
Grades.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
WebView webView; webView.setWebViewClient(new WebViewClient()
{
}webView.loadUrl(course.getString(TAG_Grade)); });
And the xml:
<TextView
android:id="#+id/textView9"
android:layout_marginLeft="110dp"
android:layout_marginTop="365dp"
android:textColor="#000"
android:textSize="14sp"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:autoLink="web"
android:onClick="onClick"
/>
Knowing that course.getString(TAG_Grade) will get the url from db but it does not work
What is the problem?

You are trying to Linkify it after the view is clicked, removed the Linkify from within the onClick.
Your going about it the wrong way.
Try this:
String userCanSeeThis = "Your Website Name";
String url = course.getString(TAG_Grade);
TextView grades = (TextView) findViewById(R.id.textView9);
grades.setText(userCanSeeThis);
addLinks(Grades, userCanSeeThis, url);
Using this helper method:
/**
* #param textView
* textView who's text you want to change
* #param linkThis
* a regex of what text to turn into a link
* #param toThis
* the url you want to send them to
*/
public static void addLinks(TextView textView, String linkThis, String toThis) {
Pattern pattern = Pattern.compile(linkThis);
String scheme = toThis;
android.text.util.Linkify.addLinks(textView, pattern, scheme, new MatchFilter() {
#Override
public boolean acceptMatch(CharSequence s, int start, int end) {
return true;
}
}, new TransformFilter() {
#Override
public String transformUrl(Matcher match, String url) {
return "";
}
});
}
Also if you set the onClickListener in your code with grades.setOnClickListener then your don't need android:onClick="" in your XML

Used this android:clickable="true"
<TextView
android:id="#+id/textView9"
android:layout_marginLeft="110dp"
android:layout_marginTop="365dp"
android:textColor="#000"
android:textSize="14sp"
android:clickable="true"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:autoLink="web"
android:onClick="onClick"
/>

Instead of using Linkify i would prefer the below line:
Html.fromHtml(course.getString(TAG_Grade));

TextView myWebSite = new TextView(this);
myWebSite .setText("http://www.google.com/");
Linkify.addLinks(myWebSite , Linkify.WEB_URLS);

You have received enough answers regarding Linkify, but there is one more subtile error crawling in your code:
You are mistaking the attribute his android:onClick with the method onClick of an View.onClickListener:
The attribute android:onClick works as followed:
Name of the method in this View's context to invoke when the view is
clicked. This name must correspond to a public method that takes
exactly one parameter of type View. For instance, if you specify
android:onClick="sayHello", you must declare a public void
sayHello(View v) method of your context (typically, your Activity).
As for the onClick-method provided by the View.onClickListener-interface:
view.setOnClickListener(...)
Register a callback to be invoked when this view is
clicked. If this view is not clickable, it becomes clickable.
Which will allow you to override the function :
public abstract void onClick (View v)
which is called when a view has been clicked.

Related

How can I link some text of a TextView to an Activity?

I would like to link some text on a TextView to an Activity. This is the TextView that I have:
<TextView
android:id="#+id/termsLink"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/terms"
android:layout_weight="4"/>
where #string/terms is:
<string name="terms">Accept terms & conditions..</string>
If I had a link to a webpage I would do it like this:
TextView link = (TextView) findViewById(R.id.termsLink);
link.setMovementMethod(LinkMovementMethod.getInstance());
but I do not know how to start an Activity when I press the link as when it is a real link (that it links a webpage).
EDIT: Please note that I do not have to handle the onClick event in the full text because the link is only on the part "terms & conditions".
EDIT 2: I have tried using two TextView as suggested on the comments and one of the answers below to make the same effect. But sometimes (depending on the screen) the "terms & conditions" part occupy two lines because it does not fill properly on the available space so the second line it is shown on the second TextView and not on the begining of the second line.
The effect is similar to this:
Accept terms &
conditions.
and I would like that it would be like this:
Accept terms &
conditions.
Thanks in advance!
Create a helper class with inner onClick listener
public class ClickSpan extends ClickableSpan {
private String url;
private OnClickListener listener;
public ClickSpan(String url, OnClickListener listener) {
this.url = url;
this.listener = listener;
}
#Override
public void onClick(View widget) {
if (listener != null) listener.onClick(url);
}
public interface OnClickListener {
void onClick(String url);
}
}
Then convert existing span into clickable one
public static Spannable createClickableSpans(Spanned original, ClickSpan.OnClickListener listener) {
SpannableString result = new SpannableString(original);
URLSpan[] spans = result.getSpans(0, result.length(), URLSpan.class);
for (URLSpan span : spans) {
int start = result.getSpanStart(span);
int end = result.getSpanEnd(span);
int flags = result.getSpanFlags(span);
result.removeSpan(span);
result.setSpan(new ClickSpan(span.getURL(), listener), start, end, flags);
}
return result;
}
So, final usage would be like
TextView link = (TextView) findViewById(R.id.termsLink);
link.setMovementMethod(LinkMovementMethod.getInstance());
link.setText(createClickableSpans((Spanned)link.getText(), new ClickSpan.OnClickListener(){
#Override
public void onClick(String url){
//Handle URL on text view click
}
}));
To make only part of a TextView clickable, you can use a spannable inside the TextView and set an onClick event listener. From here, you launch the activity with an intent as usual. You can limit the clickable section of the text by specifying the character positions (start to end)
Checkout this answer by #becomputer06
How to set the part of the text view is clickable
You should probably separate the text into 2 text views one with the terms and condition and one with just the accept.It would make things cleaner and easier. The following TextView is assuming its just for accept.
In the layouts corresponding java class(example: activity_main -> MainActivity):
public void start_activity(View view){
Intent newActivityIntent = new Intent(this,NewActivity.class);
startActivity(newActivityIntent);
}
NewActivity.class is just the name of the activity you want to start.
public class MainActivity extends AppCompatActivity {
protected void onCreate(Bundle savedInstanceState) {
....
}
public void start_activity(View view){
.....
}
}

Different layouts on listview VS firebase constant updating

I'm trying to make a chat app out of a FireBase sample. I want to make it that when the same user sends a message twice there is no header on the second message. I made it so the header's size is 0dp if current user is the same as the last user, but when I scroll or even hide the keyboard the listview updates and messes it up (all headers dissappear). Can I make it check the element above or is there another way?
public class ChatListAdapter extends FirebaseListAdapter<Chat> {
// The mUsername for this client. We use this to indicate which messages originated from this user
private String mUsername;
private Typeface Consolas;
private String lastUsername = "";
public ChatListAdapter(Query ref, Activity activity, int layout, String mUsername) {
super(ref, Chat.class, layout, activity);
this.mUsername = mUsername;
this.Consolas = Typeface.createFromAsset(activity.getAssets(), "fonts/Consolas.ttf");
}
/**
* Bind an instance of the <code>Chat</code> class to our view. This method is called by <code>FirebaseListAdapter</code>
* when there is a data change, and we are given an instance of a View that corresponds to the layout that we passed
* to the constructor, as well as a single <code>Chat</code> instance that represents the current data to bind.
*
* #param view A view instance corresponding to the layout we passed to the constructor.
* #param chat An instance representing the current state of a chat message
*/
#Override
protected void populateView(View view, Chat chat) {
// Map a Chat object to an entry in our listview
String author = chat.getAuthor();
if (!author.equals(lastUsername)) {
TextView authorText = (TextView) view.findViewById(R.id.author);
authorText.setText(author);
// If the message was sent by this user, color it differently
if (author != null && author.equals(mUsername)) {
authorText.setTextColor(Color.RED);
} else {
authorText.setTextColor(Color.parseColor("#e4de33"));
}
authorText.setTypeface(Consolas);
TextView message = (TextView) view.findViewById(R.id.message);
message.setText(chat.getMessage());
message.setTextColor(Color.WHITE);
message.setTypeface(Consolas);
TextView date = (TextView) view.findViewById(R.id.date);
date.setText(chat.getDate());
date.setTextColor(Color.WHITE);
date.setTypeface(Consolas);
lastUsername = mUsername;
} else {
view.findViewById(R.id.divider).setLayoutParams(new LinearLayout.LayoutParams(0, 0));
view.findViewById(R.id.header).setLayoutParams(new LinearLayout.LayoutParams(0, 0));
TextView message = (TextView) view.findViewById(R.id.message);
message.setText(chat.getMessage());
message.setTextColor(Color.WHITE);
message.setTypeface(Consolas);
}
}
Layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<LinearLayout
android:id="#+id/divider"
android:layout_height="1dp"
android:layout_width="fill_parent"
android:background="#color/background_darkblue"
android:orientation="horizontal" />
<LinearLayout
android:id="#+id/header"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal">
<ImageView
android:layout_width="#dimen/avatar_size"
android:layout_height="#dimen/avatar_size"
android:padding="#dimen/avatar_padding"
android:src="#drawable/g"/>
<TextView
android:id="#+id/author"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"/>
<TextView
android:id="#+id/date"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="end"
android:layout_gravity="center_vertical"/>
</LinearLayout>
<TextView
android:id="#+id/message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="#dimen/avatar_padding"
android:layout_marginRight="#dimen/avatar_padding"
android:layout_marginBottom="#dimen/avatar_padding" />
</LinearLayout>
Your code assumes that populateView() is called for each chat message in order. That is not necessarily the case, so you should come up with another way to find if the previous message is from the same user.
The FirebaseListAdapter.populateView() method now takes an extra parameter int position. With this parameter you an explicitly check whether the message before the current one is by the same user:
protected void populateView(View view, Chat chat, int position) {
String author = chat.getAuthor();
String previousAuthor = (position > 0) ? getItem(position-1).getAuthor();
if (!author.equals(previousAuthor)) {
...
So I fixed it by doing this:
String author = chat.getAuthor();
String previousAuthor = "";
int currentIndex = getmModels().indexOf(chat);
if (currentIndex > 0) {
Chat previousObject = (Chat) getItem(currentIndex - 1);
previousAuthor = previousObject.getAuthor();
}
And in the parent class I just had to create a getter for mModels. There was also another bug in this code with the layout changes because the adapter reused my changed params. The solution is to change params in both circumstances (same author and different author).

How to manipulate the contents of a button without using id; Android?

I'm new in android world and I have a problem, well, I'm making a project very simple it is about an activity where i have a button and an EditText. The button has an event onClick in XML.
My problem is it: I need the button value and send this value to
EditText but my button don't have a id. Help me I don't know how manipulate a element if it dont have a id.
XML Code:
<View
android:layout_height="#dimen/cell_height"
android:background="#color/red"/>
<Button
android:layout_marginLeft="#dimen/button_margin"
android:layout_gravity="center_vertical"
android:text="#string/hex_red"
android:textColor="#color/red"
android:onClick="copy"/>`
Java code:
public void copy(View boton){
EditText txtSelected = (EditText)this.findViewById(R.id.txtColor)
String color = boton; <-- here need the button value
txtSelected.setText(color);
}
I need your help, Thanks
you can say boton.getText().toString()
Modify your copy() function like this:
public void copy(View boton) {
EditText txtSelected = (EditText)this.findViewById(R.id.txtColor)
Button btn = (Button) boton; // << key point.
String color = btn.getText().toString();
txtSelected.setText(color);
}`
public void onClickBtn(View view) {
EditText txtSelected = (EditText)this.findViewById(R.id.txtColor)
Button btn = (Button)(view);
String value = (String) btn.getText();
txtSelected.setText(value);
txtSelected.setSelection(value.length()); // cursor will be at the end of the text
}

How to make the Textview clickable, so that it opens the url in the web browser

sorry for asking this newbie question, as i am new to android development.
what code should be entered in the main.java?
<resources>
<string name="strname">Clickable TextVisit Website</string>
</resources>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:autoLink="web"
android:text="#string/strname"
android:id="#+id/textView"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true" />
you can use Linkfy:
TextView textView = (TextView) findViewById(R.id.textView);
textView.setText("http://www.google.com");
Linkify.addLinks(textView, Linkify.WEB_URLS);
From the documentation
Linkify take a piece of text and a regular expression and turns all of
the regex matches in the text into clickable links
On textview click event write this:
Uri uri = Uri.parse("http://domain.com");
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);
that open the your URL.
Do nothing in Code just include android:autoLink="web" into your Textview XML like
<Textview . ..... .....
android:autoLink="web"/>
Above code will work to make any link clickable in TextView String...
YOURTEXTVIEWNAME.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("http://domain.com"));
startActivity(intent);
}
});
The terms here you want to know are intent, onClickListener and URI. Welcome newbie.
You can use Html.fromHtml to convert html tags in your string to links and appropriate formatting and setMovementMethod enables automatic handling of link clicks.
TextView tv = (TextView)findViewById(R.id.textView);
String s = getString(R.string.strname);
tv.setText(Html.fromHtml(s));
tv.setMovementMethod(LinkMovementMethod.getInstance());
final TextView view = (TextView) findViewById(R.id.textview);
view.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// request your webservice here. Possible use of AsyncTask and ProgressDialog
// show the result here - dialog or Toast
}
};);
I think this would help you.
And the Most importantly In android view you can define onclick service for any item in view

Click on Link in TextView

I have some text with a link in a TextView. Now I want that the browser open the link if the user click on it. My TextView looks like this:
<string name="Info">Go to Google</string>
<TextView
android:id="#+id/Info"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="#dimen/OptionMarginBottom"
android:autoLink="web"
android:linksClickable="true"
android:text="#string/Info" />
The Link is displayed correct in blue but I can not click on it. Why is that?
use this method
public static void addLink(TextView textView, String patternToMatch,
final String link) {
Linkify.TransformFilter filter = new Linkify.TransformFilter() {
#Override public String transformUrl(Matcher match, String url) {
return link;
}
};
Linkify.addLinks(textView, Pattern.compile(patternToMatch), null, null,
filter);
}
and use as
addLink(text, "^Android", "http://abhiandroidinfo.blogspot.in");
Use Linkify on your TextView
Linkify.addLinks(yourTextviewObject, Linkify.WEB_URLS);
Linkify take a piece of text and a regular expression and turns all of
the regex matches in the text into clickable links.
Helper Method:
public static void addLinks(TextView textView, String linkThis, String toThis) {
Pattern pattern = Pattern.compile(linkThis);
String scheme = toThis;
android.text.util.Linkify.addLinks(textView, pattern, scheme, new MatchFilter() {
#Override
public boolean acceptMatch(CharSequence s, int start, int end) {
return true;
}
}, new TransformFilter() {
#Override
public String transformUrl(Matcher match, String url) {
return "";
}
});
}
Now use like Below:
String weblink = "WebsiteName";
String url = course.getString(TAG_Info);
TextView txtInfo= (TextView) findViewById(R.id.Info);
txtInfo.setText(userCanSeeThis);
addLinks(txtInfo, weblink, url);
Easier method is to make a string and add Link Text
and in the xml file, make the textView:
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:autoLink="web"
android:text="#string/string_with_link" />

Categories

Resources