how to automatically make a text highlighted in android - android

in my android application the user can send feedback
public void c_send_send(View v) {
Uri uri = Uri.parse("mailto:xx#xx.net");
Intent send = new Intent(Intent.ACTION_SENDTO, uri);
send.putExtra(Intent.EXTRA_SUBJECT, "feedback");
send.putExtra(
Intent.EXTRA_TEXT,
DeviceInformation(getResources().getString(R.string.app_name),
getResources().getString(R.string.app_version)));
startActivity(Intent.createChooser(send, "feedback"));
}
public static String DeviceInformation(String app_name, String app_version) {
String EnterTextHere = "[Enter Text Here]";
Spannable spanText = Spannable.Factory.getInstance().newSpannable(EnterTextHere);
spanText.setSpan(new BackgroundColorSpan(0xFFFFFF00), 1, 17, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
String info = "\n" + spanText + "\n\n\n\nDevice Model: "
+ android.os.Build.MANUFACTURER
+ " " + android.os.Build.MODEL + "\nAndroid Version: "
+ Build.VERSION.RELEASE + "\nApplication Version: "
+ app_version;
return info;
}
the question how can i make
[Enter Your Text Here]
highlighted as shown in the picture posted in the link below
Example

Spannable strings are a very good way to use different styling in a single string. try exploring its different functions.

You can make it highlighted by the Toast option in android
Toast.makeText(getApplicationContext(), (String)data.result, Toast.LENGTH_LONG).show();

Related

Android SpannableStringBuilder for multiple Patterns

I have different screens for different entities which are Products, Rooms, Posts, and, Users.
All of them have distinct ID which I use to open the particular screen to try to load the data from the ID parameter passed on the relevant screen/activity via the APIs.
The mechanism I thought for Products,Rooms,and Posts in particular are that on Notifications Screen and alike, I want to send coded or tagged string; like below for Products for example:
You have bid on <p244 24LED Lampshade />
And to match the above I have a regular expression:
<p([0-9]*)\s(.*?)\/>(\s|$)
Here's a sample string:
String dummyText = "Hi #dan we product test <p1337 product />" +
"\n how about <r123 Room name/> is a nice room" +
"\n what <t234 this post details more about it/> but you should " +
"\n #poprocks woah one #sad";
It seems to work fine with single use of the product/post/room, but it messes up with more instances of the coded/tagged string.
But like I stated, with multiple instances like the following test:
String dummyText = "Hi #dan we product test <p1337 product /> and were more happy with <p53 car/> " +
"\n eh <r123 Room name/> is a nice room and <r233 dans house/> sucked while <r123 fun time/> was ok " +
// "\n what <t234 this post details more about it/> but you should " +
"\n <t234 view this as well/>" +
"\n #poprocks woah one #sad";
It messes up:
Here's my entire code process:
String dummyText = "Hi #dan we product test <p1337 product /> and were more happy with <p53 car/> " +
"\n eh <r123 Room name/> is a nice room and <r233 dans house/> sucked while <r123 fun time/> was ok " +
// "\n what <t234 this post details more about it/> but you should " +
"\n <t234 view this as well/>" +
"\n #poprocks woah one #sad";
List<Pattern> patternsList = new ArrayList<>();
patternsList.add(Pattern.compile(REGEX_NOTI_ROOMS)); //0
patternsList.add(Pattern.compile(REGEX_NOTI_PRODUCTS)); //1
patternsList.add(Pattern.compile(REGEX_NOTI_TWEETS)); //2
patternsList.add(Pattern.compile(REGEX_NOTI_MENTION)); //3
patternsList.add(Pattern.compile(REGEX_ARABIC_N_NUM_HASHTAG)); //4
holder.row_noti_messageTV.setText(makeSpannable(dummyText, patternsList));
holder.row_noti_messageTV.setMovementMethod(new PkMovementMethod());
Where the relevant regex are:
public static final String REGEX_NOTI_ROOMS ="<r([0-9]*)\\s(.*?)\\/>(\\s|$)";
public static final String REGEX_NOTI_PRODUCTS ="<p([0-9]*)\\s(.*?)\\/>(\\s|$)";
public static final String REGEX_NOTI_TWEETS ="<t([0-9]*)\\s(.*?)\\/>(\\s|$)";
public static final String REGEX_ARABIC_N_NUM_HASHTAG ="#(\\w*[0-9a-zA-Zء-ي٠-٩]+\\w*[0-9a-zA-Zء-ي٠-٩])";
public static final String REGEX_NOTI_MENTION ="(?:^|\\s|$|[.])#[\\p{L}0-9_]*";
And my makeSpannable method is:
public SpannableStringBuilder makeSpannable(String rawText, List<Pattern> listofPatterns) {
// StringBuffer sb = new StringBuffer();
SpannableStringBuilder spannable = new SpannableStringBuilder(rawText);
for(int i=0; i<listofPatterns.size(); i++)
{
Matcher matcher = null;
if(i==0) //init only
matcher = listofPatterns.get(i).matcher(rawText);
else
matcher = listofPatterns.get(i).matcher(spannable);
while (matcher.find()) {
showLogMessage("jsonParse", "hit on iteration" + i + " group == " + matcher.group());
if(i==3 || i == 4)
{
try {
String abbr = matcher.group();
showLogMessage("jsonParse", "loop[3 | 4 are normal] == " + i + " group(0) == " + abbr);
int start = matcher.start();
int end = matcher.end();
NotificationSpan ourSpan = new NotificationSpan(Color.BLUE, Color.RED, Color.TRANSPARENT, new IdTitleStore(abbr, abbr, abbr), NotificationAdapter.this);
spannable.setSpan(ourSpan, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
} catch (Exception e) {
e.printStackTrace();
}
}
else if(i<=2) {
try {
String orgGroup = matcher.group();
// get the match
String abbr = matcher.group(2);
showLogMessage("jsonParse", "loop == " + i + " group2 == " + abbr);
int startPoint = matcher.start();
int endPoint = matcher.end();
NotificationSpan ourSpan = new NotificationSpan(Color.RED, Color.BLUE, Color.TRANSPARENT, new IdTitleStore(matcher.group(1), abbr, orgGroup), NotificationAdapter.this);
Spannable spanText = new SpannableString(abbr);
spanText.setSpan(
ourSpan, 0, abbr.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
);
spannable.replace(startPoint, endPoint, spanText);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
return spannable;
}
Note: NotificationSpan is a custom span I use to store the group(1) as it has the ID and from group(0) I can deduce on click whether it may be a Post, Product, or a Room entity to open it.
Any feedback shall be appreciated, even if it can point me towards the right direction. Like if my approach in itself is fundamentally wrong or something, please do let me know.
EDIT: Someone pointed out at comments to remove the redundant (\s|$) from the Regular Expressions, and it did seemingly nothing
Logs for the dummyString I tested:
String dummyText = "Hi #dan we product test <p1337 product /> and were more happy with <p53 car/> " +
"\n eh <r123 Room name/> is a nice room and <r233 dans house/> sucked while <r123 fun time/> was ok " +
"\n what <t233 this post details more about it/> but you should " +
"\n <t234 view this as well/>" +
"\n #poprocks woah one #sad";
E/jsonParse: hit on iteration0 group(0) == <r123 Room name/>
E/jsonParse: hit on iteration0 group(0) == <r233 dans house/>
E/jsonParse: hit on iteration0 group(0) == <r123 fun time/>
E/jsonParse: hit on iteration1 group(0) == <p1337 product />
E/jsonParse: hit on iteration1 group(0) == <p53 car/>
E/jsonParse: hit on iteration2 group(0) == <t234 view this as well/>
E/jsonParse: hit on iteration3 group(0) == #dan
E/jsonParse: hit on iteration4 group(0) == #poprocks
E/jsonParse: hit on iteration4 group(0) == #sad
It is also weird that the first instance is not detected by the matcher at all.
i.e
"\n what <t234 this post details more about it/> but you should "
It may entirely be possible that something is wrong with the logic itself of the Multiple Patterns being matched inside loops, but I really can't seem to figure it out. Appreciate the comment though!
EDIT EDIT*: I think I finally understand what the problem was/is. Adding dot after the replace method it gave me two suggestions, notify() and notifyAll(), which got me wondering this is indeed multi-thread based operation (sort of obvious to others but yeah!). So the multiple loop was in fact the issue.
Since replacing a call updates the span itself, the inner loop (while mathcer.find()) did not have the latest span on the matcher, it had different/previous one, which would've worked fine if there were only one instance found, but since in case of multiple the start and end were way off and hence some unintended stuff was happening. Followings the updated code, I did keep the (\s|$) just in case a Product/Post/Room is the end of the string so it does match and not remain blank.
public SpannableStringBuilder makeSpannable(String rawText, List<Pattern> listofPatterns) {
SpannableStringBuilder spannable = new SpannableStringBuilder(rawText);
Matcher matcher = null;
for(int i=0; i<listofPatterns.size(); i++)
{
matcher = listofPatterns.get(i).matcher(spannable.toString());
while (matcher.find()) {
showLogMessage("jsonParse", "hit on iteration" + i + " group == " + matcher.group());
if(i<=2) {
try {
String orgGroup = matcher.group();
// get the match
String abbr = matcher.group(2);
showLogMessage("jsonParse", "span txt of iteration " + i + " going to be group2 == " + abbr);
int startPoint = matcher.start();
int endPoint = matcher.end();
NotificationSpan ourSpan = new NotificationSpan(Color.RED, Color.BLUE, Color.TRANSPARENT, new IdTitleStore(matcher.group(1), abbr, orgGroup), NotificationAdapter.this);
Spannable spanText = new SpannableString(abbr);
spanText.setSpan(
ourSpan, 0, abbr.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
);
spannable.replace(startPoint, endPoint-1, spanText);
matcher = listofPatterns.get(i).matcher(spannable);
} catch (Exception e) {
e.printStackTrace();
}
}
else {
try {
String abbr = matcher.group();
showLogMessage("jsonParse", "span txt of iteration " + i + " going to be group(0) == " + abbr);
int start = matcher.start();
int end = matcher.end();
NotificationSpan ourSpan = new NotificationSpan(Color.BLUE, Color.RED, Color.TRANSPARENT, new IdTitleStore(abbr, abbr, abbr), NotificationAdapter.this);
spannable.setSpan(ourSpan, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
return spannable;
}
Additional note: I think it'd be better if I explain why I've divided the loop into two parts to begin-with as well. The reason is simple, first 3 of my REGEX I 100% know for sure have group(2) elements, which I have implemented the click ID mechanism of. The last two are normal hashtag and mention ones which don't have group(2).
Here's the final working look, hope I don't face any performance issues:

How to format font in print receipt with thernal bluetooth printer

I make a POS project. I want to print receipt. I'm using thermal printer zonerich. I had successfully to print the receipt. Now, I want to custom the font. I want to make the outlet name bigger ,have a bold style and in center.
In my code bellow, when i try to put the bold format it will bold all of the receipt not only the outlet name. Please tell me how to make style only in outlet name and how to change the font size, Sorry for bad english. Thanks for your help.
public void IntentPrint(String notaID, String namaKasir, String date, String total, String pay, String change, String method) {
db = new DatabaseHandler(MainActivity.this);
String payment="";
String sosmed = "\n"+ sessionStartUp.getUserDetails().get(sessionStartUp.KEY_SOSMED);
String namaOtlet = sessionStartUp.getUserDetails().get(sessionStartUp.KEY_OUTLET);
String header ="\nReceipt : " + db.getFakeNotaID(notaID) + "\n" +
"Nama Kasir : " + namaKasir + "\n" +
"Date : " + date+"\n"+
"Name Qty Price"+"\n";
if(!pay.equals("0"))
{
payment ="\nTotal : "+total+"\n"+"Method : "+method+"\n"+
"Payment : "+pay+"\n"+
"Change : "+change;
}
else
payment ="\nTotal : "+total+"\n"+"\nMethod : "+method+"\n";
InitPrinter();
try {
outputStream.write(header.getBytes());
outputStream.write(data(notaID).getBytes());
outputStream.write(payment.getBytes());
outputStream.write(sosmed.getBytes());
byte[] format= { 27, 33, 0 };
byte[] center = { 0x1b, 'a', 0x01 };
byte[] arrayOfByte1 = { 27, 33, 0 };
format[2] = ((byte)(0x8 | arrayOfByte1[2]));
outputStream.write(center);
outputStream.write(format);
outputStream.write(namaOtlet.getBytes(),0,namaOtlet.getBytes().length);
outputStream.close();
socket.close();
} catch (Exception ex) {
value += ex.toString() + "\n" + "Excep IntentPrint \n";
// Toast.makeText(this, value, Toast.LENGTH_LONG).show();
}
}

Format text in AlertDialog.Builder

I am unable to get text in an AlertDialog to display in bold or italic.
I've tried formatting directly and also using the CharSequence utilties from the Android string-resource page but I always get just plain text.
What am I doing wrong?
MyFragment.java
String idFormatted = String.format(resources.getString(R.string.id));
CharSequence idStyledText = Html.fromHtml(idFormatted);
CharSequence nameItalic = Utilities.italic(resources.getString(R.string.name));
String typeFormatted = String.format(resources.getString(R.string.type));
CharSequence typeStyledText = Html.fromHtml(idFormatted);
AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
builder.setPositiveButton("Dismiss",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
}
}).setIcon(android.R.drawable.ic_dialog_info);
builder.setMessage( idFormatted + myData.getId() + "\t\t" + nameItalic + myData.getName() + "\t\t" + typeFormatted + myData.getType() );
Dialog dialog = builder.create();
dialog.setTitle("Details");
dialog.show();
strings.xml
<string name="id"><i>Id: </i></string>
<string name="name"><i>Name: </i></string>
<string name="type"><i>Type: </i></string>
Edit: -------------------------------------------------------------
Mohammad Arman suggests that the strings from the string.xml will not retain the html. This seems likely to be true, though I can't prove it yet.
Based on his and Farbod Salamat-Zadeh's answer, I tried the code below, but still the result is the same, just plain text.
Spanned idLabel = Html.fromHtml("<i>" + resources.getString(R.string.id) + "</i>");
Spanned nameLabel = Html.fromHtml("<i>" + resources.getString(R.string.name) + "</i>");
Spanned typeLabel = Html.fromHtml("<i>" + resources.getString(R.string.type) + "</i>");
...
builder.setMessage(idLabel.toString() + myData.getId() + "\t\t" + nameLabel + myData.getName());
Edit2: -----------------------------------------------------------
I've tried as Keelan has suggested:
<string name="italic_string"><![CDATA[<i>italic-string</i>]]></string>
and then:
String formattedText = getString(R.string.italic_string);
Spanned result = Html.fromHtml(formattedText);
builder.setMessage(result);
This works.
You can't simply store HTML in a strings.xml file. You need to put them in CDATA, like so:
<string name="id"><![CDATA[<i>Id: </i>]]></string>
Then to display a formatted string, you still need to use Html.fromHtml().
You can get text anywhere to display in bold or italic - I use the following;
Spanned italicText = Html.fromHtml("<i>" + "My italic text" + "</i>");
Spanned boldText = Html.fromHtml("<b>" + "My boldtext" + "</b>");
// You can use different HTML tags depending on what you want.
You need to format the html version in a separate String variable in Java class (otherwise for some reason it won't work).
String myId = <i>Id: </i>;
String myName = <b>Name: </b>
Then you have to add this in the textView like bellow:
textView1.setText(Html.fromHtml(myId +" "+ "1234");
textView2.setText(Html.fromHtml(myName +" "+ "Al Lelopath")
Why your approach is not working
It's because as you are importing the string from string.xml it will lose the attribute and send it as a plain text. And that's why Android could not take that as html.

Reference string resource from code

I have the following string declared in strings.xml:
<string name="last_msg">Your last click was on</string>
Now when someone clicks a button, I want a textview to show this string, with a space, then a variable value that is a timestamp.
Unfortunately, using #string/last_msg isn't working, and I'm not sure how to do this properly so I'm not hardcoding in content.
Here's my code for the onClick function:
public void showMsgNow(View view) {
TextView lastMsg = (TextView)findViewById(R.id.textView2);
long currentTimeStamp = System.currentTimeMillis();
lastMsg.setText(#string/last_msg + " " + currentTimeStamp);
}
I'm a newbie, any help would be great !
I found the answer on Google:
getString(R.string.last_msg)
you cant access String directly by #, for that you need to have context resource and then just do this...
lastMsg.setText(context.getResources().getString(R.string.last_msg) + " " + currentTimeStamp);
in your case use
<string name="last_msg">Your last click was on %1$s</string>
implementation:
public void showMsgNow(View view) {
TextView lastMsg = (TextView)findViewById(R.id.textView2);
long currentTimeStamp = System.currentTimeMillis();
lastMsg.setText(context.getResources()
.getString(R.string.last_msg, currentTimeStamp));
}
// getString is method of context
if (this instanceof Context)
//If you are in Activity or Service class
lastMsg.setText(getString(R.string.last_msg)+ " " + currentTimeStamp);
else
//you need to context to get the string
lastMsg.setText(getString(mContext,R.string.last_msg)+ " " + currentTimeStamp);
public String getString(Context mContext, int id){
return mContext.getResources().getString(id);
}
use below line
lastMsg.setText(getString(R.string.last_msg) + " " + currentTimeStamp);
Try this :
lastMsg.setText(R.string.last_msg + " " + new SimpleDateFormat(d-MM-YYYY).format(new Date()));

Android: How to append formatted text to android.text.Editable?

Within a TagHandler which I passed to Html.fromHtml(), I would like to append some formatted text to the given Editable output object, which then gets passed to a TextView.
Appending plain text with output.append("my text") works fine. But how to append red or italic text?
class MyTagHandler implements Html.TagHandler {
#Override
public void handleTag(boolean opening, String tag, Editable output, XMLReader xmlReader) {
output.append("my text");
// how to append red and italic text here ?
}
}
You should be able to use Html.fromHtml and Editable.setSpan() to do it. Here's some sample code:
appendFormatted(output, "<font color=red><i>red italic</i></font>");
}
private void appendFormatted(Editable text, String string) {
final int start = text.length();
final Spanned span = Html.fromHtml(string);
text.append(span);
final int end = text.length();
for (final Object o : span.getSpans(0, span.length(), Object.class)) {
text.setSpan(o, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
If you just need some simple formatting applied, you can pass in the specific CharacterStyle derived-object to the Editable.setSpan() call - see the "Selecting, Highlighting, or Styling Portions of Text" example on the developers site.
If I understood your question right here is a way to do this
mBox = new TextView(context);
mBox.setText(Html.fromHtml("<b>" + title + "</b>" + "<br />" +
"<small>" + description + "</small>" + "<br />" +
"<small>" + DateAdded + "</small>"));
The answer was copied from a similar question here.

Categories

Resources