I am trying to edit the width of a TextView before it is getting loaded on the screen based on some score value. The requirement is like, based on the relative score value the text view should have width.
I have written the below code in onCreate() method of the activity as below,
{{{
TextView graph = (TextView) findViewById(R.id.predictionScoreGraph);
graph.getViewTreeObserver().addOnGlobalLayoutListener(
new OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
int score = 60;
UserData data = UserData.getInstance();
score = data.overallScore();
TextView graph = (TextView) findViewById(R.id.predictionScoreGraph);
int grossWidth = graph.getWidth();
Log.d(TAG, "Existing width of the text view is "
+ grossWidth);
LayoutParams existing = graph.getLayoutParams();
int fillWidth = (grossWidth * score) / 100;
Log.d(TAG, "Modified width is " + fillWidth);
graph.setWidth(fillWidth);
existing.width = fillWidth;
graph.setLayoutParams(existing);
graph.setBackgroundColor(getResources().getColor(
android.R.color.holo_green_light));
graph.getViewTreeObserver()
.removeGlobalOnLayoutListener(this);
}
});
}}}
It works like a Gem!! But when I want to do it for more than one TextView objects, it is not changing the width of the TextView object.
Can somebody please help me on how to change width of multiple TextView objects?
Thanks,
Rather than using a GlobalLayoutListener, try overriding the onMeasure method of the Activity.
Related
Trying to create a BMI Calculator I already declared a variable for weight and height, but still I'm getting an error of "variable "weight" might not have been initialized.
public class MainActivity extends AppCompatActivity {
private EditText eheight, eweight;
private Button computeb;
private TextView output, category;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
eheight = (EditText) findViewById(R.id.eheight);
eweight = (EditText) findViewById(R.id.eweight);
output = (TextView) findViewById(R.id.output);
category = (TextView) findViewById(R.id.category);
computeb = (Button) findViewById(R.id.computeb);
computeb.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
float weight, height, BMI;
if (checkInputLength())
return;
weight = Float.parseFloat(weight.getText().toString());
height = Float.parseFloat(height.getText().toString());
computeBMI(weight, height);
BMI = weight / (height * height);
}
});
}
Change
weight = Float.parseFloat(weight.getText().toString());
height = Float.parseFloat(height.getText().toString());
to
weight = Float.parseFloat(eweight.getText().toString());
height = Float.parseFloat(eheight.getText().toString());
weight and height are just float variables.If you want to parse data from edittext then you have to get the data from the edittexts and store them in the corresponding variables.
weight.getText()? weight is a float type value which is not initialized here. I think you want to use eweight. And the same with height.
weight = Float.parseFloat(eweight.getText().toString());
height = Float.parseFloat(eheight.getText().toString());
just set it 0.
float weight = 0;
change this:
weight = Float.parseFloat(weight.getText().toString());
to:
weight = Float.parseFloat(eweight.getText().toString());
I have an EditText, a Button and a TextView. On clicking the button, textview shows the text written in edittext. Is it possible to find the size of textview occupied depending upon text. i.e. If It has three characters "abc", what is width now, if it has 5 characters like "abcde" , then what is the width ?
Rect bounds = new Rect();
Paint textPaint = textView.getPaint();
textPaint.getTextBounds(text,0,text.length(),bounds);
int height = bounds.height();
int width = bounds.width();
or
textView.setText("bla");
textView.measure(0, 0);
textView.getMeasuredWidth();
textView.getMeasuredHeight();
Please try this:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TextView edit = (TextView) findViewById(R.id.edit);
edit.setTextSize(20);
edit.setText("Hello, world");
edit.measure(0, 0);
int width = edit.getMeasuredWidth();
Log.w("width", width.toString());
}
Before you get width, you have to measure the view / label / text edit.
Please let me know if this is not working.
TextView txt = new TextView(mContext);
txt.setText("Some Text)";
int height = txt.getLineCount() * txt.getLineHeight();
int width = txt.getWidth();
Try this way,hope this will help you to solve your problem.
yourTextView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
int width = yourTextView.getMeasuredWidth();
int height = yourTextView.getMeasuredHeight();
}
});
please tell me width in??? do you want ?
TextView method getWidth() gives you width of your view, in pixels
TextView textView = (TextView)findViewById(R.id.textview);
textView.getWidth(); //width of your view, in pixels
Im creating a app that takes in a string and divides it into words and reprints them while checking if there is a '#' in front of the words. If there is a '#' the color of that word is changed. The problem i am having is the String gets cut if the original String is too long.
any help?
public class MainActivity extends Activity {
String[] parts;
LinearLayout.LayoutParams layoutParams ;
int size;
LinearLayout L;
String s ="This is the test String that is divided #Testing ";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
L=(LinearLayout)findViewById(R.id.ll);
layoutParams= new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
parts = s.split(" ");
size = parts.length;
for(int i=0; i<size;i++)
{
TextView valueTV = new TextView(this);
String d= parts[i] + " ";
valueTV.setText(d);
// valueTV.setLayoutParams(layoutParams);
if(d.charAt(0)=='#')
{
valueTV.setTextColor(Color.CYAN);
}
L.addView(valueTV,layoutParams);
}
}
}
It is because you are having linear layout
and it takes horizontal orientation.
It will display the text views upto your phone edge and after that your data will not be visible.
You need to check the device display width and manually add another layout if the textView's width exceeds the display width.
Refer this link
It will help you resolve your problem.
I'm trying to make a dynamic grid layout, it being API 10+ is the part that's been making it slow going. I tried to make it wrap automatically.. but in the end found it easier just to try to force it into a grid pattern using coordinates. This script was working by itself when I did the positioning at time of creation, but now I am trying to loop through each item as a sort. So if one item is deleted, they all float back into a grid without a hole in the middle.
Problem is, it seems the layout parameters are only applying to the last object.
Here's some base variables and onCreate setup:
int screenWidth;
int screenHeight;
int distStep = 130;
int leftPad = 20;
int numCols;
int baseID = 0;
android.util.DisplayMetrics metrics = this.getResources().getDisplayMetrics();
screenWidth = metrics.widthPixels;
screenHeight = metrics.heightPixels;
numCols = (int) (screenWidth - leftPad) / distStep;
int scrRemain = screenWidth - ((numCols * distStep) + leftPad);
distStep += (int) scrRemain / numCols;
Then on to the main function for adding:
public void addObjToLayout() {
RelativeLayout relLay = (RelativeLayout) this.findViewById(R.id.mainWindow);
for(int i = 1; i <= currQuantity; i++){
TextView tv=new TextView(this);
tv.setTextSize(40);
tv.setId(baseID + i);
tv.setPadding(24, 4, 24, 4);
tv.setBackgroundColor(0x110000FF);
tv.setText(String.valueOf(baseID + i)); //Val for debugging
tv.setTextColor(0xFFFFFFFF);
relLay.addView(tv);
}
baseID += currQuantity;
sortLayout();
}
Then the sorting:
public void sortLayout() {
int leftNum = 20;
int topNum = 0;
for(int i = 1; i <= baseID; i++){
TextView tv= (TextView) this.findViewById(baseID);
MarginLayoutParams mp = new MarginLayoutParams(tv.getLayoutParams());
mp.setMargins(leftNum, topNum, 0, 0);
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(mp);
tv.setLayoutParams(lp);
leftNum += distStep;
if(leftNum >= distStep * numCols){
leftNum = leftPad;
topNum += distStep;
}
}
}
What I am getting is all the textViews pile up in the top left corner, except the last one which is positioned exactly where it should be. So it seems in my head, the params object isn't applying until the loop ends or something.. but logically I don't see why.
As I said, this worked when I set the params at the get go, problem is mass updating them all at once. I am pretty new to android, so I hope I'm not just doing something stupid.
Thanks for your time
Margin means it will set a gap between the previous view and current view.
When you add view1, view2 and view3 to grid layout and if you remove view2 at some point of time, then the margin for view3 is set according to view1. So, it won't leave empty space in place of view2. Instead of removing view2 at run time, set the background for view2 as null and set the text as empty as below.
textView.setBackground(null);
textView.setText("");
So that the view is still available but looks as deleted.
Started looking into GridView using an extended baseAdapter. Looks promising:
For more (see #2):
http://www.mkyong.com/android/android-gridview-example/
Is there a way to find out whether the text content to be placed in a TextView will fit in a single row or not?
What i want to achieve is displayed in the attached image (its a section of a listView). The problem relates to textView#3. If it is too big, i want to place it below textView#2, but if content is short enough i want to place it to right of textView#2 (scenario seen in row#3 is what i want to escape from)
So, anyone?.. How can i solve this particular problem?
I'm imagining this can't be achieved with a single layout for my listview's rows..
It is possible. You should measure text size and compare it against TextView size. If text width > textView width than it is too long.
You can learn about text measuring from this post.
also you can use TextView's built-in features and make it single line and set text ellipsize method.
A solution (& not a pretty one) is to do some math on the space occupied in the textView by your strings. In my particular case i've added 2 textViews (3 & 3B) & depending on what my math calculations say - i would use just one & hide the other.
Details:
in the getView method of your adapter find out the width of the parent listView
public View getView(int position, View convertView, ViewGroup parent) {
int listViewWidth = parent.getWidth();
calculate occupied space by other textViews placed in same row (just textView2 in my case);
Paint paint = textViewX.getPaint();
occupiedWidth = (int) (occupiedWidth +paint.measureText("text to be placed in textview"));
compare space occupied by text to be placed in the last textview ( in my screenShot textView3, same formula to calculate width) & compare with space left (listViewWidth - occupiedWidth)
set the text on the correct textView & hide the other
.. improve the code as needed
There is no in-build function to compare this.
After doing to many research and code i have build my own function to do this...
1) copy this code to your project
import android.app.Activity;
import android.content.res.Resources;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.widget.TextView;
public class TextMeasure {
public static boolean isTextCanFitInTextView(TextView textView, String txt , float allowWidthInDp , Activity activity){
String backupText = textView.getText().toString();
textView.setText(txt);
textView.measure(0, 0); //must call measure!
float textViewSize_px = textView.getMeasuredWidth(); //get width in px
// Converts dip into its equivalent px
float dip = allowWidthInDp;
Resources r = activity.getResources();
float allowView_px = TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
dip,
r.getDisplayMetrics()
);
//restore textView
textView.setText(backupText);
return textViewSize_px <= allowView_px;
}
public static boolean isTextCanFitInTextView_matchParent(TextView textView, String txt , float totalMarginInDp, Activity activity){
String backupText = textView.getText().toString();
textView.setText(txt);
textView.measure(0, 0); //must call measure!
float textViewSize_px = textView.getMeasuredWidth(); //get width in px
// Converts dip into its equivalent px
float dip = totalMarginInDp;
Resources r = activity.getResources();
float totalMarginInDp_px = TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
dip,
r.getDisplayMetrics()
);
float allowView_px;
float window_length;
window_length = getDisplayWidthInPixel(activity);
allowView_px = window_length - totalMarginInDp_px;
//re store textView
textView.setText(backupText);
return textViewSize_px <= allowView_px;
}
private static float getDisplayWidthInPixel(Activity activity){
DisplayMetrics metrics = new DisplayMetrics();
activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
return metrics.widthPixels;
}
}
2) Use above class method to do your text and textView comparison , for eg :
1) Know exact width , android:layout_width="300dp"
TextView yourTextView = findViewById(R.id.txt);
float widthOfTextView_inDp = 300f; // width of textView Size in dp (densityPixel) , what you set in xml view
String yourTxt = "your text need to display in single line";
if (TextMeasure.isTextCanFitInTextView(yourTextView,yourTxt,widthOfTextView_inDp,this)){
// text can fit in to text View
yourTextView.setText(yourTxt);
}else {
// text can't fit in to text View
// add your logic
}
2) match_parent used to set width.
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:layout_width="match_parent"
TextView yourTextView = findViewById(R.id.txt);
float totalMargin_inDp = 20f; // width of text view is match_parent and (marginStart = 10dp), (marginEnd = 10dp) = 20dp, note: it is total margin from both end of mobile screen combine.
String yourTxt = "your text need to display in single line";
if (TextMeasure.isTextCanFitInTextView_matchParent(yourTextView,yourTxt,totalMargin_inDp,this)){
// text can fit in to text View
yourTextView.setText(yourTxt);
}else {
// text can't fit in to text View
// add your logic
}
try this property of textview
android:maxLength="number of characters you want to display in textview"
now in Actvity check if string length is > maxLength than change the postion of your view.