android make links in a TextView clickable - android

First, I'll start by saying I've visited this two:
question 1 about this subject, question 2 about this subject
and both have failed me.
Second, my app is based on a single map fragment, i don't know if that's an issue, but the TextView is part of an info window which is displayed over the map.
I have the following TextView in xml:
<TextView
android:id="#+id/tv_link"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="20dp"
android:linksClickable="true"
android:autoLink="web" />
which I want to make into a link, I'm feeding the text programatically, and can see the text as it is, but it is not clickable, or "hyper-link"ed.
The following is the part where I set up the TextView in my activity:
TextView tvLink = (TextView) v.findViewById(R.id.tv_link);
// make the link clickable
tvLink.setClickable(true);
tvLink.setMovementMethod(LinkMovementMethod.getInstance());
String text = (String) urls.get(arg0.getTitle());
// Setting the link url
tvLink.setText(Html.fromHtml(text));
I have also tried making the TextView have attribute of android:onClick="openBrowser" and have this class openBroweser:
public void openBrowser(View view){
//Get url from tag
String url = (String)view.getTag();
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.addCategory(Intent.CATEGORY_BROWSABLE);
//pass the url to intent data
intent.setData(Uri.parse(url));
startActivity(intent);
}
but it also didn't work. I might have made a mess while trying the different approached, but I did try to separate each try. and am confused and in need of an outside look.
EDIT 1 :
added the following:
My string in the res file (inside a string-array)
Click here for more info about this location
(which works here, so I assume it should be a legal link as needed)
My whole XML file as requested in comment
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="#+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textStyle="bold"
android:layout_gravity="center_horizontal"
/>
<TextView
android:id="#+id/tv_info"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<TextView
android:id="#+id/tv_link"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="20dp" />
</LinearLayout>
<ImageView
android:id="#+id/iv_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:layout_gravity="center_horizontal"
android:layout_marginTop="20dp"
/>

What you are trying to do will not work because a Google Maps InfoWindow is not a live view.
In the documentation for Custom Info Windows it states:
The info window that is drawn is not a live view. The view is rendered
as an image (using View.draw(Canvas)) at the time it is returned. This
means that any subsequent changes to the view will not be reflected by
the info window on the map. To update the info window later (for
example, after an image has loaded), call showInfoWindow().
Furthermore, the info window will not respect any of the interactivity
typical for a normal view such as touch or gesture events. However you
can listen to a generic click event on the whole info window as
described in the section below.
and
As a result, any listeners you set on the view are disregarded and you
cannot distinguish between click events on various parts of the view.
So the clicks on the individual tv_link TextView within the overall InfoWindow layout will not be processed.
You need to use the OnInfoWindowClickListener to listen for clicks on an InfoWindow

To begin with take out:
android:linksClickable="true"
android:autoLink="web"
Like this:
<TextView
android:id="#+id/tv_link"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="20dp"/>
This is working for me with a hard coded url. I suspect the way you are formatting your url is not correct.
String text = (String) urls.get(arg0.getTitle());
I'm not sure what you are getting from this, if you are using an array of strings.
The two questions you have linked to both use this format:
String text = "<a href='http://www.google.com'> Google </a>";
Link text
You need to format your string resources like this:
<string name="txtCredits">Google</string>
I cannot see how your custom class openBrowser is fetching the string in the right format for you.
I suggest you log everything.
String text = (String) urls.get(arg0.getTitle());
Log.i("url = ", text);
tvLink.setText(Html.fromHtml(text));

Use below which will do all your task
String str = holder.restContactInfoTV.getText().toString();
int index = str.lastIndexOf(",");
SpannableString snstr = new SpannableString(str);
ClickableSpan Span = new ClickableSpan() {
#Override
public void onClick(View textView) {
try {
String mobile = CUrrentOrderChild
.getRestaurantMobileCO();
Intent intent = new Intent(Intent.ACTION_CALL,
Uri.parse("tel:" + mobile));
startActivity(intent);
} catch (Exception e) {
}
}
#Override
public void updateDrawState(TextPaint ds) {
// TODO Auto-generated method stub
super.updateDrawState(ds);
// ds.setColor(Color.RED);
//ds.setUnderlineText(true);
}
};
snstr.setSpan(Span, index + 2, snstr.length(),
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
holder.restContactInfoTV.setText(snstr);
holder.restContactInfoTV.setMovementMethod(LinkMovementMethod.getInstance());

Related

How to change the text field value from fragment to button click event

Click on the button event.
public void onClick(View view) {
Button result = view.findViewById(view.getId());
textNo[R.id.t1].setText("2");
Toast.makeText(getActivity(),"클릭 : " + result.getText().toString(),Toast.LENGTH_SHORT).show();
}
For example, is there a way to change the value of the first text view by clicking the first button?
There are countless buttons, so I gave resource id to each button and text
Now, for example, only 5 buttons and text views are given.
for (i = 0; i < 5; i++) {
String textId = "t" + (i + 1);
String buttonId = "b" + (i + 1);
textNo[i] = view.findViewById(getResources().getIdentifier(textId, "id", getActivity().getPackageName()));
buttonNo[i] = view.findViewById(getResources().getIdentifier(buttonId, "id", getActivity().getPackageName()));
When I press the button on the same line, I want to increase the number of text views located on it, but I kept trying, but I couldn't figure out how to do it in the fragment.
enter image description here
The outline of the XML code is as follows.
<TextView
android:id="#+id/t1"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_weight="1"
android:gravity="center"
android:text="#string/zero" />
<Button
android:id="#+id/b1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/button"
android:layout_weight="1"
android:text="#string/Click"
style="?android:attr/buttonBarButtonStyle" />
It's my first time asking this question, so I'm very inexperienced, but if you tell me, I'll try harder.
I'm sorry that I'm not good at English.
b1.setOnClickListener {
t1.text = "tttt"
}
If u have only a few buttons, you can write them in xml. For more, use horizontal RecyclerView.
You should use RecyclerView in this case. Your method isn'n correct

TextView, how to display prompt for user

I need to set prompt for my TextView, if String is too long to fit inside TV (i set max length 20) then it displays only part of it with "..." at the end. I want to display prompt with full String when i click on TV. Is it possible? And if yes then how to do it?
Inside activity:
textCompany.setText(testDb.getCompanyName(id));
textCompany.setEllipsize(null);
And XML:
<TextView
android:id="#+id/textCompany"
android:layout_width="match_parent"
android:layout_below="#+id/textId"
android:layout_height="wrap_content"
android:maxLength="20"
android:ellipsize="end"
android:gravity="end"
android:layout_marginEnd="20dp"
android:textSize="17sp"
android:text="verylongstringjusttotestifthisworksandletshopeitwill" />
You can do that with a simple onClickListener. First, you check what the length of the text is, then if it's more than 20 characters, you take the first 20 and add three dots to the end and display that. At the same time, you save the full text to a temporary variable, and you display it when someone clicks your TextView.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final TextView textView = findViewById(R.id.textCompany);
String shortMessage;
final String message = textView.getText().toString();
if(message.length() >= 20){
shortMessage = message.substring(0,19)+"...";
textView.setText(shortMessage);
}
textView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG).show();
}
});
}
Note: make sure you make your textView clickable by adding the following to your xml:
android:clickable="true"
The behavior you mentioned is due to
android:ellipsize="end"
It displays the end of text with "Some text..." if it does not fit in width.
You can programmatically change the ellipsize value to none to display the full text on Click.
myTextView.setEllipsize(null);

linkify on textview with domain in text not working, links not clickable

I'm not able to linkfy a string with a href when the string says the domain name with it. so string. let me show you.
Here is the string:
<string name="go_to_settings">Please go to "Settings" in mywebsite.com to change this status</string>
And it would say this to the user: "Please go to "Settings" in mywebsite.com to change this status. "
here is the textview I'm using:
<TextView
android:id="#+id/tv_instructions"
android:layout_width="280dp"
android:layout_height="wrap_content"
android:layout_marginTop="73dp"
android:lineSpacingExtra="3sp"
android:textAlignment="center"
android:textColor="#5c5c5c"
android:textColorLink="#color/action_blue"
android:linksClickable="true"
android:text="#string/go_to_settings"/>
and here is how i am trying to make the link clickable:
Linkify.addLinks(tv_instructions, Linkify.ALL)
tv_instructions.movementMethod=LinkMovementMethod.getInstance()
But i am seeing happen on api 24 and 27 device and emulator is that the link is going to www.mywebsite.com instead of www.mywebsite/settings
but here is the strange thing, if i change the text the user sees and remove .com from that then it works fine. so if the user see this instead it works:
and it would say this to the user: "Please go to "Settings" in mywebsite to change this status. "
notice there is no .com being mentioned. How can i get this displayed. i also tried this way:
tv_instructions.text=(utils.fromHTML(resources.getString(R.string.go_to_settings),null))
tv_instructions.movementMethod=LinkMovementMethod.getInstance()
and textview like this:
<TextView
android:id="#+id/tv_instructions"
android:layout_width="280dp"
android:layout_height="wrap_content"
android:layout_marginTop="73dp"
android:lineSpacingExtra="3sp"
android:textAlignment="center"
android:textColor="#5c5c5c"
android:text="#string/go_to_settings"
/>
you guys have any idea what I'm doing wrong ?
Figured this out. for some reason i needed to wrap my text as character data using tag cData in my strings file. this works:
<string name="go_to_settings"><![CDATA[Please go to "Settings" in mywebsite.com to change this status :]]></string>
then the textview looks like this:
<TextView
android:id="#+id/tv_instructions"
android:layout_width="280dp"
android:layout_height="wrap_content"
android:layout_marginTop="73dp"
android:lineSpacingExtra="3sp"
android:text="#string/go_to_settings"
android:textAlignment="center"
android:textColor="#5c5c5c"
android:textColorLink="#color/action_blue"/>
Java Code
tv_instructions.text=(utils.fromHTML(resources.getString(R.string.go_to_settings),null))
tv_instructions.movementMethod=LinkMovementMethod.getInstance()
linkify on textview with domain in text not working, links not clickable
You can also use ClickableSpan
If an object of this type is attached to the text of a TextView with a movement method of LinkMovementMethod, the affected spans of text can be selected. If selected and clicked, the onClick(View) method will be called.
Check below SAMPLE CODE
Try this
public class MainActivity extends AppCompatActivity {
TextView myTextView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myTextView = (TextView) findViewById(R.id.myTextview);
setSpan();
}
private void setSpan() {
SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder("Please go to \"Settings\" in");
SpannableString spannableString = new SpannableString(" mywebsite.com ");
ClickableSpan clickableSpan = new ClickableSpan() {
#Override
public void onClick(View textView) {
Toast.makeText(MainActivity.this, "Click", Toast.LENGTH_SHORT).show();
// you can open your link here as per your requiremnt
}
};
spannableString.setSpan(clickableSpan, 0, spannableString.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
spannableString.setSpan(new UnderlineSpan(), 0, spannableString.length(), 0);
spannableStringBuilder.append(spannableString);
spannableStringBuilder.append("to change this status");
myTextView.setText(spannableStringBuilder);
myTextView.setMovementMethod(LinkMovementMethod.getInstance());
}
}

Android - Using Buttons With Single Layout

I have created an Activity that uses the ViewFlipper to Switch between Different elements. Each element represents an Item in a store. I would like to add a "Buy" Button to each View. I am however not sure how to do this, since all the views use the default layout i have created. I have added the information like the Price of the Item etc Programmatically. So i am uncertain how to add a listener to the button, since they will all refer to the same button in the xml file:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<Button
android:id="#+id/credit_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_marginBottom="220dp"
android:layout_marginLeft="30dp"
android:layout_marginRight="30dp"
android:layout_marginTop="104dp" />
<TextView
android:id="#+id/credit_type"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignRight="#+id/credit_button"
android:layout_alignTop="#+id/credit_button"
android:layout_marginRight="22dp"
android:layout_marginTop="21dp"
android:text="Large Text"
android:textAppearance="?android:attr/textAppearanceLarge"
android:typeface="normal" />
<TextView
android:id="#+id/credit_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/credit_button"
android:layout_alignRight="#+id/credit_type"
android:layout_centerVertical="true"
android:layout_marginBottom="30dp"
android:layout_marginLeft="15dp"
android:text="Medium Text"
android:textAppearance="?android:attr/textAppearanceMedium" />
</RelativeLayout>
As you can see, the Button id is "Credit Button". So now to be able to differentiate between the different store items' buttons what would i have to do?
Note, i am adding store items dynamically as well, so i cant simply create all the views separately using xml.
OK HERE IS THE UPDATED ANSWER. I used everyones responses below to fix teh issue. So Thank you all :)
// PerkView
View PerkView = View.inflate(this, R.layout.store_category, null);
viewFlipper.addView(PerkView);
Button perkButton = (Button)
PerkView.findViewById(R.id.StoreCatItem);
// TitleView
View TitleView = View.inflate(this, R.layout.store_category, null);
viewFlipper.addView(TitleView);
Button titleButton = (Button)
TitleView.findViewById(R.id.StoreCatItem);
// ProfileView
View ProfileView = View.inflate(this, R.layout.store_category, null);
viewFlipper.addView(ProfileView);
Button profileButton = (Button)
ProfileView.findViewById(R.id.StoreCatItem);
I simply Created Multiple Views Programmatically, and then retrieved the buttons from those views afterwards. I then added the listeners to the buttons as follows:
perkButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent i = new Intent(getBaseContext(), Perks.class);
i.putExtra("player", player);
startActivity(i);
}
});
titleButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent i = new Intent(getBaseContext(), Titles.class);
i.putExtra("player", player);
startActivity(i);
}
});
Thanks A lot :)
There are two ways you can handle the button click distinctly,
At the time of inflating layout for each store, add the button listener with onClick() method there only.
Or you can assign some uniqueId or flag to each store and then handle button click of store by this uniqueID.
Usually you solve this by following stack:
fragment -has-> list -has-> adapter -has-> list of items
Normally if you present one item per screen and you want to swipe between you should use ViewPager with FragmentStatePagerAdapter (allows removing items from ViewPager if needed).
http://developer.android.com/reference/android/support/v4/view/ViewPager.html
For more items in one screen use ListView with BaseAdapter as it allows better control over item view and ListView will recycle views as you scroll or fling.
http://developer.android.com/guide/topics/ui/layout/listview.html
Set unique tag for each store button, in code you can differentiate with respect to tags.Tag is just piece of information you want set for any view, u can use it.Implement on click listener in your activity and then set that to all buttons, so all buttons click run through same code where you can easily diffrentiate between ur store buttons with respect to tags.
like below how you can set and get tag
// for setting tag
Button button = (Button) findViewById(R.id.button1);
button.setTag("unique_tag");
// get tag and then differentiate with the unique_tg
button.getTag();
You can easily create your button programmatically like so :
Button b = new Button(this); // where this = your context
b.setText("Buy");
// b."other attribute" = "other value";
b.setTag("Awesome blue shirt");
b.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Button buy = (Button) v;
String article = b.getTag();
// do some stuff
}
});
container.addView(b);
You can identify the buy button using its tag, as seen here.

setGravity not working

Please see my code below. I am unable to make SetGravity work.
How come?
Layout Code:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:padding="25dp"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:longClickable="true"
android:orientation="vertical" >
<EditText
android:id="#+id/etCommands"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:hint="Type a command"
android:password="true" />
<LinearLayout
android:weightSum="100"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:layout_weight="20"
android:id="#+id/btnResults"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Results" />
<ToggleButton
android:paddingBottom="10dp"
android:layout_weight="80"
android:id="#+id/passTog"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="ToggleButton" android:checked="true"/>
</LinearLayout>
<TextView
android:id="#+id/tvResults"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="invalid" />
</LinearLayout>
java code:
public class TextPlay extends Activity {
private static final String TAG = "MyApp";
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.text);
Button chkCmd = (Button) findViewById(R.id.btnResults);
final ToggleButton passTog = (ToggleButton) findViewById(R.id.passTog);
final EditText input = (EditText) findViewById(R.id.etCommands);
final TextView display = (TextView) findViewById(R.id.tvResults);
passTog.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (passTog.isChecked()) {
input.setInputType(InputType.TYPE_CLASS_TEXT
| InputType.TYPE_TEXT_VARIATION_PASSWORD);
} else {
input.setInputType(InputType.TYPE_CLASS_TEXT);
}
}
});
chkCmd.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
String check = input.getText().toString();
Log.i(TAG, "Check Value is: " + check);
if (check.contentEquals("left")) {
Log.i(TAG, "I am under left ");
display.setGravity(Gravity.LEFT); //WHYW ILL YOU NOT WORK SETGRAVITY?????????????
} else if (check.contentEquals("center")) {
display.setGravity(Gravity.CENTER);
} else if (check.contentEquals("right")) {
display.setGravity(Gravity.RIGHT);
}
else if (check.contentEquals("blue")) {
display.setGravity(Gravity.RIGHT);
}
}
});
}
}
I just tested and it works.. You might be doing a few things wrong;
First of all, when you type "left" into the text field, are you making sure that you didn't type "Left" (most keyboards capitalize the first letter)
If you are sure about the above, do you see the log that says "I am under left " (Not the "Check is")? If not, then it's not getting there somehow..
If you are indeed seeing it, you might want to clean/build your project (in Eclipse Project-> Clean -it does cleaning and re-building)
If that doesn't work neither, you might want to change your target build (change it to API level 10 or so) You don't really need to worry about the target build if you are just using this as an exercise to learn.
I think we're not able to change UI this way.
I usually do like this.
TableLayout table1 = (TableLayout) findViewById(R.id.table1);
txtresult.setGravity(Gravity.RIGHT);
((TableLayout) table1).addView(txtresult);
It works with me.
So I suggest you to do a trick like delete that TextView "display" and generate a new one with new Gravity properties.
Hope it works!
Linh
Try to set layout_gravity="center" and layout_width="wrap_ontent" maybe that will do it :)
set layout_width="wrap_content" and set the layout gravity.
Have you tried to call invalidate after you change the layout attribute of your text view?
Android Documentation - View.invalidate()
Change the conditions as below:
check.equalsIgnoreCase("left")
Hope this solves ur problem.
View.invalidate() must be involved on UI thread. If you are doing the view re-configuration within a Listener callback which is your case, then you probably need call View.postInvalidate(), check out the API:
public void invalidate ()
Since: API Level 1
Invalidate the whole view. If the view is visible, onDraw(android.graphics.Canvas) will be called at some point in the future. This must be called from a UI thread. To call from a non-UI thread, call postInvalidate().
Try this:
<LinearLayout
android:id="#+id/llResults"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center">
<TextView
android:id="#+id/tvResults"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="invalid" />
</LinearLayout>
Instead of Doing :- tvResults.setGravity
try setting gravity of linearlayout :- llResults.setGravity
your code works good for me, i´ve tested on a real device with android 4.0.3 (Nexus S), the only thing that can be bothering you its capital letters as #Tolga E told.
you can try:
check.equalsIgnoreCase("left")
instead of:
check.contentEquals("left")
and debugging, put a breakpoint on the if´s to check that your code is actually trying to modify the gravity or its skipping that line.
Hope it helps.
If anyone who's following thenewboston's tutorial stumbles upon this with the same problem, it's an issue with the display variable. Just change
final TextView display = (TextView) findViewById(R.id.tvDisplay);
to
final TextView display = (TextView) findViewById(R.id.tvResults);
up with the other variable declarations.
I think setGravity method has been depreciated from API 4.0 . I don't see any alternative. Only way left you need to use API level 8.0. I am also getting nulpointer exceptions in log cat by using setGravity method
Set your TextView's width as android:layout_width="fill_parent"then you can set it programmatically using myTextView.setGravity(Gravity.CENTER) .

Categories

Resources