I have a TextView showing the name of a parameter, the value of the parameter and a unit. (Like "speed 5 m/s")
Since I need the value to change it's color i am using a Handler to switch between two Strings. Both of these strings have html-code injected, so i can change the color without the need to have more than one TextView.
My problem now is that if i have a dash ('/') inside my string, all characters after it will not be shown.
If i replace the slash inside my string it works. But that's not really solution.
private void setBlinkText(){
try{
strBlinkOff = "speed <font color='#fafafa'>12</font> m/s";
strBlinkOn = "speed <font color='#212121'>12</font> m/s";
m_displayLine.setText(strBlinkOff.substring(0, strBlinkOff.indexOf('<')));
m_displayLine.append(Html.fromHtml(strBlinkOff.substring(strBlinkOff.indexOf('<'), strBlinkOff.indexOf("font>")), Html.FROM_HTML_MODE_LEGACY));
m_displayLine.append(strBlinkOff.substring(strBlinkOff.indexOf("font>") + 5));
m_blinkHandler = new Handler();
final String strFinalBlinkOn = strBlinkOn;
m_blinkHandler.postDelayed(new Runnable()
{
#Override
public void run()
{
m_displayLine.setText(strFinalBlinkOn.substring(0, strFinalBlinkOn.indexOf('<')));
m_displayLine.append(Html.fromHtml(strFinalBlinkOn.substring(strFinalBlinkOn.indexOf('<'), strFinalBlinkOn.indexOf("font>")), Html.FROM_HTML_MODE_LEGACY));
m_displayLine.append(strFinalBlinkOn.substring(strFinalBlinkOn.indexOf("font>") + 5));
m_blinkHandler.postDelayed(new Runnable()
{
#Override
public void run()
{
setBlinkText(p_strMessage);
}
}, 800);
}
}, 300);
} catch(Exception e)
{
Toast.makeText(getContext(), "Error", Toast.LENGTH_SHORT).show();
}
}
m_displayLine should show "speed 12 m/s" but instead just shows "speed 12 m/"
Edit: The TextView looks like this:
<TextView
android:id="#+id/ToolTextLine2"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginStart="12dp"
android:layout_marginEnd="12dp"
android:background="#color/accentGreenLight"
android:fontFamily="#font/lordmeg09"
android:maxLength="16"
android:maxLines="1"
android:paddingStart="12dp"
android:paddingEnd="12dp"
android:paddingTop="8dp"
android:paddingBottom="8dp"
android:textColor="#2d373c"
android:textSize="28sp"
app:autoSizeTextType="uniform"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/guidelineTool2" />
It works without the autosizing and a smaller textsize. But why does it get cut off?
Looks like the maxLines attribute was getting ignored cause i was appending the text to my TextView after already setting it. I fixed it by setting
m_displayLine2.setLines(1);
again after appending all parts of my string.
Try using / instead of /
Related
I have two textviews in one horizontal layout, the first is normal text and the second is clickable with a different color.
XML
<!--inside rootlayout..-->
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_margin="10dp"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:gravity="center_horizontal"
android:maxLines="2"
android:text="By clicking sign up, you agree to our "
android:textColor="#color/black"
android:textSize="12sp"/>
<TextView
android:textStyle="bold"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="terms and conditions"
android:textColor="#color/colorPrimary"
android:textSize="12sp"
android:clickable="true"/>
</LinearLayout>
And It gives me a great look on large screens (4.7 inch and above),
but when the screen size is lower, the second textview gets weird.! I want it to automatically position itself below the first textview or to make their parent layout orientation vertical..!!
here's how it looks.!
Update #1
why the ForegroundColorSpan won't change!? it always shows blue or black no matter what color resources I set.!??
private void handleTermsConditions() {
SpannableStringBuilder stringBuilder = new SpannableStringBuilder(termsTxt.getText());
stringBuilder.setSpan(new StyleSpan(Typeface.BOLD), 38, 58, 0);
int color = ContextCompat.getColor(RegistrationActivity.this, R.color.colorPrimary);
ForegroundColorSpan fcs = new ForegroundColorSpan(color);
stringBuilder.setSpan(fcs, termsTxt.getText().length() - 20, termsTxt.getText().length(),
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
ClickableSpan clickableSpan = new ClickableSpan() {
#Override
public void onClick(View widget) {
Toast.makeText(RegistrationActivity.this, "Click", Toast.LENGTH_SHORT)
.show();
}
};
stringBuilder.setSpan(clickableSpan, 38, 58, Spanned.SPAN_POINT_MARK);
termsTxt.setMovementMethod(LinkMovementMethod.getInstance());
termsTxt.setText(stringBuilder);
}
The same question here or from the original document
DisplayMetrics displayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
int height = displayMetrics.heightPixels;
int width = displayMetrics.widthPixels;
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
Get the height and width of your device and use the values to decide whether to set screen to portrait or not:
if ((height == <value>) && (width == <value>)) {
setRequestedOrientation (ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
*Feel free to modify as required in your activity
for your requirement you don't have to use 2 text views for this you can place a spannable string builder on just 1 text and put clickable as well as color property and you are done.
Code:
TextView textView = findViewById(R.id.tvSample);
SpannableStringBuilder stringBuilder =new SpannableStringBuilder(textView.getText());
stringBuilder.setSpan(new ForegroundColorSpan(Color.BLUE),textView.getText().length()-20,textView.getText().length(),Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
stringBuilder.setSpan(new ClickableSpan() {
#Override
public void onClick(final View view) {
Toast.makeText(MainActivity.this,"Click",Toast.LENGTH_LONG).show();
}
},textView.getText().length()-20,textView.getText().length(),Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(stringBuilder);
Here is example of putting different spans on text view
This is how to set two spans on single text view
You can set TextView Font size or width according to screen size using value folder. Try like this.
You can use most easy way Android Spannable property for doing this. and by that way you can do this work by single textview and can manage your click events.
Here is code for doing this.
public void setHighLightedText(TextView textView, String textToHighlight) {
String tvt = textView.getText().toString();
int ofe = tvt.indexOf(textToHighlight, 0);
ClickableSpan clickableSpan = new ClickableSpan() {
#Override
public void onClick(View textView) {
// here you do all stuff
}
#Override
public void updateDrawState(TextPaint ds) {
super.updateDrawState(ds);
ds.setColor(0xff0000ff);
ds.setUnderlineText(true);
// Here you can put your style on textview.
}
};
SpannableString wordtoSpan = new SpannableString(textView.getText());
for (int ofs = 0; ofs < tvt.length() && ofe != -1; ofs = ofe + 1) {
ofe = tvt.indexOf(textToHighlight, ofs);
if (ofe == -1)
break;
else {
wordtoSpan.setSpan(clickableSpan, ofe, ofe + textToHighlight.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(wordtoSpan, TextView.BufferType.SPANNABLE);
textView.setMovementMethod(LinkMovementMethod.getInstance());
}
}
}
You can see onClick method in it. there you can set click or use callback if you put this code in Utility class.
Bonus
Also this is the right way to do this.
Either use Fragments
OR
Try autoSizeText
<TextView
.......
android:autoSizeTextType="uniform"
................................../>
Here is something about it on android developer site
I have an EditText and when I set it to Empty and Click on my Button, my App crashes.
When I view it in Android Monitor it points to the line:
final int addTm = Integer.parseInt(Teaching);
Here is my code:
LinearLayout
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="2dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_weight="1"
android:text="" />
<EditText
android:id="#+id/tM"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="24dp"
android:layout_marginRight="50dp"
android:ems="1"
android:inputType="number"
android:maxLength="1"
android:text="0" />
<Button
android:id="#+id/submitBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Submit" />
</LinearLayout>
And my Java Code:
Submit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String Teaching = Tm.getText().toString();
final int addTm = Integer.parseInt(Teaching);
FirebaseDatabase database = FirebaseDatabase.getInstance();
DatabaseReference myRef = database.getReference("sub").child("TM");
myRef.runTransaction(new Transaction.Handler() {
#Override
public Transaction.Result doTransaction(MutableData mutableData) {
Integer currentValue = mutableData.getValue(Integer.class);
if (currentValue == null) {
mutableData.setValue(0);
} else {
mutableData.setValue(currentValue + addTm);
}
return Transaction.success(mutableData);
}
#Override
public void onComplete(DatabaseError databaseError, boolean committed, DataSnapshot dataSnapshot) {
System.out.println("Transaction completed");
}
});
}
});
The other answers are good, but I'd recommend wrapping with a try/catch for the NumberFormatException. I know you have the input set to accept numbers only, but always better safe than sorry.
Lowercase the String variable Teaching. In Java we only upper case Type names. (classes, interfaces, etc.) Notice how StackOverflow is highlighting the variable Teaching blue, a bit disorienting no?
Do this for your member fields as well Tm and Submit. They should be written tm and submit. Also, Tm is not a very descriptive name for a variable either. Imagine another programmer coming in and looking at your code, and wondering what a tm is. What is the context of this tm, where does it come from... what does it do? Is it a Teenage Mutant?
Regardless when using Integer.parseInt wrap it in a try/catch:
#Override
public void onClick(View view){
final int addTm;
try {
String teaching = Tm.getText().toString();
addTm = Integer.parseInt(teaching);
} catch (NumberFormatException e) {
addTm = 0;
}
// ...
}
Why should you do this? What if I enter a decimal number into your number input?
Using your accepted answer you will still crash. Integer.parseInt does not parse decimal numbers.
Or how about, if I switch the locale of the device and enter a number with odd characters that Integer.parseInt won't expect.
Gotta catch that exception to be full proof.
When executing Integer.parseInt() on an empty string it throws an NumberFormatException.
First, check the value of Teaching, and verify it's not empty string, or - try/catch for NumberFormatException, and set the value you want for Teaching in that case.
I have a LinearLayout ll inside the other LinearLayout inside the ScrollView
<ScrollView
android:layout_width="270px"
android:layout_height="fill_parent" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center_horizontal"
android:orientation="vertical" >
<LinearLayout
android:id="#+id/gifcreator_thumbs"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:orientation="vertical" />
<Button
android:id="#+id/gifcreator_add"
android:layout_width="250px"
android:layout_height="125px"
android:layout_margin="10px"
android:textColor="#000000"
android:text="Добавить кадр" />
</LinearLayout>
</ScrollView>
In onCreate I'm running the update_frames() method:
public void update_frames(String a)
{
Log.e("EmSy", "Updating Frame # " + a);
try
{
File f = new File(a);
tag = ll.getChildCount();
View v = getLayoutInflater().inflate(R.layout.gifcreator_item, null);
v.setTag(tag);
v.setOnLongClickListener(new OnLongClickListener() {
public boolean onLongClick(View v)
{
delete_frame(Integer.parseInt(v.getTag().toString()));
return true;
}
});
ImageView thumb = (ImageView)v.findViewById(R.id.gircreator_item_thumb);
TextView desc = (TextView)v.findViewById(R.id.gifcreator_item_desc);
Bitmap t = BitmapFactory.decodeFile(a);
Bitmap t2 = Bitmap.createScaledBitmap(t, 110, 110, false);
thumb.setImageBitmap(t2);
desc.setText("Кадр №" + tag);
data.add(new GIFFrame(t, 42, a));
ll.addView(v);
}
catch (Exception e)
{
Toast.makeText(this, e.toString(), Toast.LENGTH_LONG).show();
e.printStackTrace();
}
}
Here's the delete_frame method:
public void delete_frame(int tag_for_deleting)
{
try
{
ll.removeAllViews();
data.remove(tag_for_deleting);
temp_data = data;
data.clear();
for (GIFFrame gf : temp_data)
{
update_frames(gf.p);
frames.notify();
}
temp_data.clear();
}
catch (Exception e)
{
Toast.makeText(this, e.toString(), Toast.LENGTH_LONG).show();
e.printStackTrace();
}
}
So, before executing delete_view method all views has been added, but after executing that method the views aren't adding to the ll. My code stops on the ll.addView(v) line, so I have the rigth path to the file in my LogCat:
`ru.mso.gb - EmSy - Updating Frame # /sdcard/pic.png`
Why it isn't working?
in your code, when you longpress a view, the main idea is to delete THE view, though you seem to remove all views, delete_frame(int tag_for_deleting) should remove one view, not all the views, as made by this line ll.removeAllViews();
get the index of your view, and execute this instead
ll.removeViewAt(index)
EDIT:
After reading your code again, it looks like when you want to delete 1 single line, you delete everything and build your layout from scratch, this is BAD, very BAD, instead, remove the one view you want to remove by the line I posted above, and remove the one info from the arraylist, that's it
Problem here
temp_data = data;
data.clear();
You just add new reference to data, then clear it. This means code in the loop never run.
You can do the following
replace
temp_data = data;
with
temp_data = new ArrayList<your type here>(data)
Need some help debugging my code. I am very new to the Android SDK and am working on learning it. From what I can glean from several posts on SO and other google search results... I formulated this code.
public class MainMenu extends Activity {
private int str = 8, dex = 8, inte = 8, luk = 8, stats = 20;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getActionBar().setDisplayShowHomeEnabled(false);
getActionBar().setDisplayShowTitleEnabled(false);
setContentView(R.layout.activity_main_menu);
}
As you can see, I have created a few private variables my app is going to use to store data. In order to interact with these values, I will redraw the TextView each time they are modified. *Feel free to correct me here if this is not an ideal strategy.
public void strup(View view) {
if(stats > 0) {
TextView tv = (TextView)findViewById(R.id.textView4);
TextView st = (TextView)findViewById(R.id.textView18);
str++;
stats--;
tv.setText(str);
st.setText(stats);
} else {
Toast.makeText(this, "Out of stats!", Toast.LENGTH_SHORT).show();
}
I use a button with the following format.
Str [X] [+1]
Where Str [X] is TextView with X a dynamic value.
Also where [+1] is a button with an Onclick function preset by the XML file.
<TextView
android:id="#+id/textView9"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Str [" />
<TextView
android:id="#+id/textView4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="8" />
<TextView
android:id="#+id/textView13"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="]" />
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="strup"
android:text="+1" />
Now for simplicity, I have altered the "android:text="" " lines to reflect their actual values instead of linking to #string/... I don't think this makes of much difference but I wanted to acknowledge it.
So my question is why does my Application crash when I click the "+1" button? All my app is trying to do is to redraw the TextView with a higher value (under str) and a lower value (under stats).
Thanks for any and all help!
You are passing integer value in settext. Either cast integer to string or you can try changing settext like this:
tv.setText(""+str);
st.setText(""+stats);
You tried to create this object:
TextView st = (TextView)findViewById(R.id.textView18);
where is textView18 in the xml?
u can caste using toString method like this:
tv.setText(str.toString());
st.setText(stats.toString());
Try this change the position of your setContentView(R.layout.activity_main_menu);
public class MainMenu extends Activity {
private int str = 8, dex = 8, inte = 8, luk = 8, stats = 20;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_menu);
getActionBar().setDisplayShowHomeEnabled(false);
getActionBar().setDisplayShowTitleEnabled(false);
}
I have an editText that fills half the screens width, and all of it's height. When I append text to it the text always starts halfway down the edit text height and when it gets to the edge to the editText it keeps writing, scrolling to the right. I want it to go to a new line, why isn't it? and why does it start half way down? At the moment the text on the left should be replicated on the right. AppendToEMulator writes to the terminal fine, but when i'm ssetting the text in the editText on the right there are no newlines from either the bytes received, probably as I convert it to a string and also none from when the end of the editText is reached, just keeps going right.
<jackpal.androidterm.emulatorview.EmulatorView
android:id="#+id/emulatorView"
android:layout_width="500dp"
android:layout_height="wrap_content"
android:layout_above="#+id/term_entry"
android:layout_below="#+id/deviceConnect"
android:layout_toRightOf="#+id/scrllyout"
android:focusable="true"
android:focusableInTouchMode="true" />
<EditText android:id="#+id/outputBox"
android:layout_toRightOf="#+id/emulatorView"
android:layout_alignParentRight="true"
android:layout_width="200dp"
android:layout_height="fill_parent"
android:background="#ffffff"
android:textColor="#FF043241"
android:inputType="text|textImeMultiLine" />
In Java:
public void onDataReceived(int id, byte[] data) {
dataReceived = new String(data);
dataReceivedByte = dataReceived.getBytes();
statusBool = true;
((MyBAIsWrapper) bis).renew(data);
runOnUiThread(new Runnable(){
#Override
public void run() {
mSession.appendToEmulator(dataReceivedByte, 0, dataReceivedByte.length);
}});
final String ReceivedText = mReceiveBox.getText().toString() + " "
+ new String(data);
runOnUiThread(new Runnable() {
public void run() {
mReceiveBox.setText(ReceivedText);
mReceiveBox.setSelection(ReceivedText.length());
}
});
viewHandler.post(updateView);
}
Answer was that setting an inputType disables wordwrap via:
android:singleLine="true"
Even if I specify
android:singleLine="false"
it was still getting overridden.
As I do not need to type in the editText I simply removed the input type.