This question already has answers here:
Android: textview hyperlink
(9 answers)
Closed 8 years ago.
In my android app how can i show hyperlinks as clickable links to open in browser .
For this I am fetching json messages from backend , saving the data in SQLite database of app and then displaying them on screen using TextView -
Fetching json messages using AsyncTask and Progress Dialog -
protected Void doInBackground(Void... params) {
//some code goes here
mMessages = json.getJSONArray(TAG_MESSAGES);
// looping through all posts according to the
// json
// object returned
for (int i = 0, length = mMessages.length(); i < length; ++i) {
JSONObject c = mMessages.getJSONObject(i);
// gets the content of each tag and put in
// database
String content = c.getString(TAG_MESSAGE);
// add field in database and update
db.addFieldInGcm(content);
}
}
In onPostExecute() i am refreshing the screen with all messages saved in database using TextView lblMessage object -
// show messages on screen
TextView lblMessage;
lblMessage.setText("");
List<String> messages = db.getAllGCMMessages();
for (int k = messages.size() - 1; k >= 0; --k) {
lblMessage.append(messages.get(k).toString() + "\n\n");
This is my XML layout for lblMessage -
<TextView
android:id="#+id/lblMessage"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="2dip"
android:padding="5dip"
android:textColor="#000000"
android:textStyle="bold"
android:textSize="16dip"
android:autoLink="all" ></TextView>
Seems like , XML android:autoLink is not applicable for strings fetched from database .
So , if while displaying messages i use something like -
if( messages.get(k).toString().contains("http://www.") )
How can i change this string in clickable hyperlinks using java ?
Thank you
Use Linkify.addLinks(textView, Linkify.ALL).
This is my working implementation after getting answers -
private void showMessage() {
// TODO Auto-generated method stub'
// show messages on screen
lblMessage.setText("");
List<String> messages = db.getAllGCMMessages();
for (int k = messages.size() - 1; k >= 0; --k) {
String message = messages.get(k).toString();
lblMessage.append(message + "\n\n");
}
Linkify.addLinks(lblMessage, Linkify.ALL);
}
and to change color of hyperlinks , i editted my xml for textview -
android:textColorLink="#69463d"
Related
I'm working on an app that generates passwords randomly using the array. The password is in TextView. Everything is good unless I want to generate a new password second time. How can I "delete" the old text (password) from the TextView and replace it with the new one using the same button?
Here are the variables that I'm using:
EditText dlugosc;
String haslo = "";
String pustak = "";
TextView haslo0;
And this is a code that I use to generate a password:
(znaki is the name of array)
dlugosc = findViewById(R.id.password_len);
haslo0 = findViewById(R.id.password);
String yui = dlugosc.getText().toString();
int x = Integer.parseInt(yui);
for(int i = 0; i < x; i++){
int Index = generator.nextInt(znaki.length);
haslo = znaki[Index] + haslo;
}
I have already tried doing an if structure:
if (haslo0 != null){
haslo0.setText(pustak);
haslo0.setText(haslo);
}
else
haslo0.setText(haslo);
But it doesn't help :(
When I want to have 7 chars in the password and click the button first time, the result is correct e.g. PKAjzQL. But when I click the button second time, the result is nBzcRjQPKAjzQL instead of nBzcRjQ.
Why are you appending the old string haslo behind the newly generated one in haslo = znaki[Index] + haslo;
Probably that's why you are getting output like that. Can you please try just setting newly generated password into the textview like
haslo = znaki[Index];
And then try to set text in the text view using haslo0.setText(haslo);
How can I "delete" the old text (password) from the TextView and replace it with the new one using the same button?
The problem is not to "delete" the old text, the problem is that you have to clear the list for example, every time user clicks on the Button you clear the list doing : znaki.clear(), then it will only show the new password generated.
If you see your output :
First output :
PKAjzQL --> This is correct
Second output :
nBzcRjQPKAjzQL --> this is the new output + the old one
Can you give the code of the OnClickButton? And why are you setting the same TextView with diferents Strings when you click?
haslo0.setText(pustak);
haslo0.setText(haslo);
?
I am working on Watson Conversation chatbot. I have been trying to implement the 'options' response type in my chatbot application. My problem is "Creating 'n' number of dynamic buttons in Android where n is the number of label names of options present in the backend(IBM Watson Conversation)"
I have been able to retrieve the label names in form of text. Now I have to put these label names in "clickable buttons". Such that when a user clicks on a button, a value is passed to the backend (Watson Conversation API).
This is how I am retrieving option(response type) from backend. Watson Conversation sends reply in form of JSON.
Label name retrieving code:
str = response.getOutput().getGeneric().get(i).getResponseType();
JSONArray arrayOptions = new JSONArray(response.getOutput().getGeneric().get(i).getOptions());
int j=0; //j is used to count the number of options
while (j<arrayOptions.length()){
final Message outMessage2 = new Message();
outMessage2.setMessage(response.getOutput().getGeneric().get(i).getOptions().get(j).getLabel());
outMessage2.setId("2");
System.out.println(outMessage2);
messageArrayList.add(outMessage2);
j++;
}
Try this to solve your problem
First create a LinearLayout Layout inside xml
<LinearLayout
android:id="#+id/layout_dynamic"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:orientation="vertical">
</LinearLayout>
After that, use below code
LinearLayout layout_dynamic =(LinearLayout) findViewById(R.id.layout_dynamic);
for (int i = 0; i < YOURARRAY.length(); i++) {
String label = <Button Name as You Like>;
LinearLayout childLayout = new LinearLayout(getActivity());
LinearLayout.LayoutParams linearParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT LinearLayout.LayoutParams.WRAP_CONTENT);
childLayout.setLayoutParams(linearParams);
Button btnName = new Button(getActivity());
btnName.setLayoutParams(newTableLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.WRAP_CONTENT, 1f));
childLayout.addView(btnName, 0);
layout_dynamic.addView(childLayout);}
Hope this will help you.
I'm creating my first app on android, accordingly I have low experience to develop android apps and I'm fist time use java too.
What I want ?
I want to generate table from ArrayList
What's the problem ?
I have problem when I generate table. When "for" loop finished debugger stands in catch block (but when I mouse over "e", it writes - "local variable e is not defined" and I can not read some error) after that I see on phone screen -"unfortunately app is closed"
What's happen without For Loop ?
Without For loop everything works well, when I try to show only one object.
Please help and give me suggestions, Thanx.
Hare is Java code:
try {
ArrayList<Persons> otherPersons = new ArrayList<Persons>();
otherPerosons = GetPersonsList();//from service
// /* Find Tablelayout defined in main.xml */
TableLayout tl = (TableLayout) findViewById(R.id.dynamictable);
TextView[] title = new TextView[1000];
TableRow[] tr = new TableRow[1000];
LinearLayout.LayoutParams trparams;
LinearLayout.LayoutParams titleparams;
for (int y=0; y < otherPersons.size(); y++) {
/* Create a new row to be added. */
tr[y] = new TableRow(this);
tr[y].setId(y+100);
tr[y].setLayoutParams(new TableRow.LayoutParams(TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.MATCH_PARENT));
trparams = (LinearLayout.LayoutParams) tr[y].getLayoutParams();
trparams.setMargins(0, 8, 0, 5); //substitute parameters for left, top, right, bottom
tr[y].setLayoutParams(trparams);
/* Create a TextView to be the row-content. */
title[y] = new TextView(this);
title[y].setText(otherPersons.get(y).Name);
title[y].setId(y +200);
title[y].setTextColor(Color.parseColor("#000000"));
title[y].setGravity(Gravity.LEFT);
title[y].setLayoutParams(new TableLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, 34));
titleparams = (LinearLayout.LayoutParams) title[y].getLayoutParams();
titleparams.setMargins(5, 0, 0, 0); //substitute parameters for left, top, right, bottom
title[y].setLayoutParams(titleparams);
tr[y].addView(title[y]);
/* Add row to TableLayout. */
tl.addView(tr[y], new TableLayout.LayoutParams(TableLayout.LayoutParams.FILL_PARENT, TableLayout.LayoutParams.WRAP_CONTENT));
}
} catch (Exception e) {
e.printStackTrace();
}
Hare is my Design XML:
<TableLayout
android:id="#+id/dynamictable"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:shrinkColumns="*"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginTop="39dp"
android:stretchColumns="*"
android:background="#ffB224">
</TableLayout>
I don't know the answer, but try to put your exception-output in your logcat output with
try{
}catch(Exception e){
Log.e("ClassName", e.toString());
}
Maybe you see more information about the exception.
Here you can find more information about Android Logging
I have a java code for an apk. I want to change the color from java activity
try {
String s = "";
JSONArray jArray = new JSONArray(result);
for(int i=0; i<jArray.length();i++){
JSONObject json = jArray.getJSONObject(i);
s = s +
"User : "+json.getString("username")+"\n"+
"Send : "+json.getString("time")+
" & "+json.getString("date")+"\n"+
Now, I want to set 2 different color, for the "user" one color and json.getString("username") a different color as well as font weight, bold or not.
and my XML code is
<TextView
android:id="#+id/result"
android:background="#2E2EFE"
android:layout_width="match_parent"
android:textColor="#F3F781"
android:textSize="24dp"
android:layout_height="wrap_content"
android:paddingLeft="20sp"
android:text="TextView"/>
But I do not want to change the color from XML
I am having a problem with a custom view I am currently doing for an app on android, I know there are many questions related with inflaters, but I cannot get around this problem.
the inflater i working just fine, but it should be doing the loop 3 times and is only doing it 1 so I only get one view on my final layout.
the relevant part of the code is this one
void populate(String strcline, String url){
lLfD = (LinearLayout)findViewById(R.id.lLfD);
try{
JSONArray a1 = new JSONArray(strcline);
for(int i = 0; i < a1.length(); i++){
JSONArray a2 = a1.getJSONArray(i);
final String fUserId = a2.getString(0);
String userName = a2.getString(1);
String userPicture = url + a2.getString(2);
View child = getLayoutInflater().inflate(R.layout.cellevery, lLfD);
ImageView avatar = (ImageView)findViewById(R.id.cellAvatar);
downloadFile(userPicture, avatar);
TextView cellName = (TextView)findViewById(R.id.cellName);
cellName.setText(userName);
lLfD.addView(child);
}
}catch(Exception e){
}
pDialog.dismiss();
}
You look like you need to run findViewById only on the inflated view, otherwise it will just find the first one which is only the first one in your loop:
View child = getLayoutInflater().inflate(R.layout.cellevery, lLfD);
ImageView avatar = (ImageView)child.findViewById(R.id.cellAvatar);
downloadFile(userPicture, avatar);
TextView cellName = (TextView)child.findViewById(R.id.cellName);
cellName.setText(userName);
Here's an explanation of findViewById in your loop:
Loop 1:
1LfD->child1->R.id.cellAvatar (findViewById(R.id.cellAvatar) finds this one)
Loop 2:
1Lfd->
child1->R.id.cellAvatar
child2->R.id.cellAvatar (findViewById(R.id.cellAvatar) finds the child1.cellAvatar again)
Loop 3:
1LfD->
child1->R.id.cellAvatar
child2->R.id.cellAvatar
child3->R.id.cellAvatar (findViewById(R.id.cellAvatar) finds the child1.cellAvatar again)
by using child.findViewById(R.id.cellAvatar), it ensures that you find the correct R.id.cellAvatar for each run of the loop.
Does that make sense?
Update 2:
When you call:
getLayoutInflater().inflate(R.layout.cellevery, lLfD);
You are already setting the parent view as the second argument so you don't need to call:
lLfD.addView(child);