Android: get displayed text from textview in signle line only available - android

I have single line textview. I am setting string in it. Sometimes full string not possible to display. So I just want that string which is displayed.
TextView valueTV = new TextView(context);
// valueTV.setEllipsize(TextUtils.TruncateAt.MIDDLE);
valueTV.setText(list.get(i).getTitle());
valueTV.setTag(i);
valueTV.setBackgroundColor(Color.parseColor(clr));
valueTV.setTextColor(Color.parseColor(txtclr));
if(dt1.equals(startdt))
{
valueTV.setTextColor(Color.parseColor(txtclr));
}else {
valueTV.setTextColor(Color.TRANSPARENT);
}
valueTV.setTypeface(type_thin);
valueTV.setId(list.get(i).getId());
valueTV.setMaxLines(1);
LinearLayout.LayoutParams ll=new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
ll.setMargins(0,1,0,0);
valueTV.setLayoutParams(ll);
valueTV.setOnClickListener(this);
lladd.addView(valueTV);
For Example
Full String : I am Android Developer
RIght now it displays:
I am And
So How can I get
I am And?
Thanks

I thanks both #Andriy and Sujith for helping. Mix of both answers worked for me.
ViewTreeObserver vto = valueTV.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
int end = valueTV.getOffsetForPosition(valueTV.getWidth(), 0) + 1;
String displayed = valueTV.getText().toString().substring(0, end);
System.out.println("i---displayed--" + displayed);
}
});

Try to use getOffsetForPosition(). For visible text from start something like that:
int end = textView.getOffsetForPosition(textView.getWidth(), 0) + 1;
String displayed = textView.getText().toString().substring(0, end);

ViewTreeObserver vto = textView.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
String text = (String) textView.getText().subSequence(0, textView.getLayout().getEllipsisStart(0));
Log.i(TAG, "Txt: " + text);
}
});
this gives you the text visible in textview (without three dots)

Related

findViewById with reverse search does not work

I'm confused right now. I expect, that something, which works one way, also works reversed as well. But apparently not... I'm creating a view programmatically in my the class PlayerView. In the method player_table I'm assigning an onclick listener. And that works perfectly fine. However in the class PlayerLifePoints_Functions I have created the onclick method. The method itself works fine. The problem is the following: I'm assigning id's manually (to make my work in future process steps easier). Now I can read the id from an element, which was clicked. However if I want to find exactly this element by the ID (e.g. 400) it does return an error:
Error: java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.Window$Callback android.view.Window.getCallback()' on a null object reference at ...PlayerLifePoints_Functions.onClick(PlayerLifePoints_Functions.java:21) -> The line with the log command
I have no idea why. I have also tried using getParent(), but that does not work either. Any ideas, where the problem could be?
Class PlayerView
public class PlayerView extends View {
private RelativeLayout relativeLayout;
private TableLayout tableLayout;
private int player_loop;
private int player_count;
public PlayerView(Context context, int player_count){
super(context);
setPlayer_count(player_count);
}
public ScrollView create_scrollView(){
ScrollView scrollView = new ScrollView(getContext());
ScrollView.LayoutParams scroll_params = new ScrollView.LayoutParams(
ScrollView.LayoutParams.MATCH_PARENT,
ScrollView.LayoutParams.MATCH_PARENT
);
scrollView.setLayoutParams(scroll_params);
scrollView.addView(create_relativeLayout());
return scrollView;
}
public HorizontalScrollView create_relativeLayout(){
HorizontalScrollView horizontalScrollView = new HorizontalScrollView(getContext());
relativeLayout = new RelativeLayout(getContext());
RelativeLayout.LayoutParams relativeParams = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.MATCH_PARENT,
RelativeLayout.LayoutParams.MATCH_PARENT
);
relativeLayout.setLayoutParams(relativeParams);
create_Player_Table_Layout();
horizontalScrollView.addView(relativeLayout);
return horizontalScrollView;
}
public void create_Player_Table_Layout(){
for(player_loop = 1; player_loop <= player_count; player_loop++){
relativeLayout.addView(player_table(getResources().getString(R.string.dummy_player_name) + player_loop, player_loop));
}
}
public TableLayout player_table(String playername, int playernumber){
tableLayout = new TableLayout(getContext());
tableLayout.setId(playernumber * 1000);
if (playernumber > 1) {
//TABLE PLACEMENT
RelativeLayout.LayoutParams tbl_params_New = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
tbl_params_New.addRule(RelativeLayout.RIGHT_OF, (playernumber - 1) * 1000);
tableLayout.setLayoutParams(tbl_params_New);
}
//Add Playername
TableRow row_playername = new TableRow(getContext());
TextView view_name = new TextView(getContext());
TableRow.LayoutParams view_name_params = new TableRow.LayoutParams();
view_name_params.setMargins(20,20,20,20);
view_name.setLayoutParams(view_name_params);
view_name.setGravity(Gravity.CENTER);
view_name.setText(playername);
view_name.setTextSize(20);
view_name.setId(playernumber * 100);
//OnClickListener
PlayerName_Functions listener_name = new PlayerName_Functions();
view_name.setOnClickListener(listener_name);
row_playername.addView(view_name);
tableLayout.addView(row_playername);
//Add Lifepoints
TableRow row_lifepoints = new TableRow(getContext());
TextView view_lifepoints = new TextView(getContext());
TableRow.LayoutParams view_lifepoints_params = new TableRow.LayoutParams();
view_lifepoints_params.setMargins(20, 0, 20, 20);
view_lifepoints.setText("40");
view_lifepoints.setTextSize(40);
view_lifepoints.setGravity(Gravity.CENTER);
view_lifepoints.setId(playernumber * 100 + 10);
view_lifepoints.setLayoutParams(view_lifepoints_params);
//OnClickListener
PlayerLifePoints_Functions listener_lifepoints = new PlayerLifePoints_Functions();
view_lifepoints.setOnClickListener(listener_lifepoints);
row_lifepoints.addView(view_lifepoints);
tableLayout.addView(row_lifepoints);
for(int opponent_loop = 1; opponent_loop <= player_count; opponent_loop++){
tableLayout.addView(commander_damage_from_player(player_loop, opponent_loop));
}
return tableLayout;
}
Class PlayerLifePoints (Containing the OnClick Function implemented in the class above)
public class PlayerLifePoints_Functions extends AppCompatActivity implements View.OnClickListener {
#Override
public void onClick(View v) {
TextView textView = (TextView) v;
String lp = textView.getText().toString();
int id = textView.getId();
int playernumber = Character.getNumericValue(String.valueOf(id).charAt(0));
Log.d("Test", "ID: " + findViewById(v.getId()).getId());
// Intent intent = new Intent(v.getContext(), Update_LifePoints.class);
// intent.putExtra( "Update Reason", "Test");
//// intent.putExtra("Player Name", playername);
// intent.putExtra("Lifepoints", lp);
//
// v.getContext().startActivity(intent);
}
Your class PlayerLifePoints_Functions cannot use findViewById because it does not have content. Usually activities are started with Intents and they inflate a layout by overriding the onCreate method.
If you just want to make it work, you can use:
v.getRootView().findViewById(v.getId()).getId());
In that case you do not need to extend from AppCompatActivity
Or better just get rid of the class:
view_lifepoints.setOnClickListener( View.OnClickListener {
#Override
public void onClick(View v) {
TextView textView = (TextView) v;
String lp = textView.getText().toString();
int id = textView.getId();
int playernumber = Character.getNumericValue(String.valueOf(id).charAt(0));
Log.d("Test", "ID: " + findViewById(v.getId()).getId());
}
);
In general:
I would recommend not putting your whole logic into a view, but more down into a lower layer. Having it in the activity would already be an improvement for prototyping. If your code grows, it may make sense to switch to MVP or MVVM.
Google has some great resources to get you started:
https://developer.android.com/guide/components/activities/intro-activities
https://developer.android.com/topic/libraries/architecture/

Get measure of relative layout android?

I have an empty RelativeLayout. I must get height and width of layout (set to match the parent). I have tried to search online but, to no avail. This is my code, can you help me? When I launch the application it crashes in the getCoordinate method. Sorry for my English.
public class MainActivity extends AppCompatActivity {
Random rand = new Random();
int[] coordinate = new int[2];
public void getCordinate(final RelativeLayout layout){
layout.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
// Ensure you call it only once :
layout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
coordinate[0] = layout.getMeasuredWidth();// width must be declare as a field
coordinate[1] = layout.getMeasuredHeight();// height must be declare as a fiel
}
});
}
public void makeButton(RelativeLayout play_area){
int button_x = rand.nextInt(coordinate[0]);
int button_y = rand.nextInt(coordinate[1]);
Button bomb = new Button(this);
bomb.setX((float)button_x);
bomb.setY((float)button_y);
play_area.addView(bomb);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RelativeLayout play_area = (RelativeLayout) findViewById(R.id.play_area);
play_area.measure(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);
getCordinate(play_area);
Log.d("Coordinate", "Xmax: " + coordinate[0] + " Ymax: " + coordinate[1]);
//makeButton(play_area);
}
}
you shouldn't call measure(). you could maybe just call .setLayoutParams(width, height) to set the view to match parent's width/height.
and simply calling .getMeasuredWidth() (or height) on the view should return their width/height values

ImageView scale issues

I have an ImageView (original size: 500 x 80) . I am changing its width parameter like this:
imageView1.getLayoutParams().width=(int) (500.0*width_proc);
When I use ImageView.getWidth() the result is 555, which is perfect.
When I use ImageView.getHeight() the result is still 80. It doesn't update to the new value, even though the image is automatically rescaled.
I tried to add a Sleep(100), to use ImageView.getViewTreeObserver().addOnGlobalLayoutListener, or to add measure() functions, nothing works.
Code looks like this:
...
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
View myView=this.findViewById(android.R.id.content);
myView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
public void onGlobalLayout() {
BuildGraphInterface();
}
});
}
........
public void BuildGraphInterface()
{
.......
//================= search 1 ===========================//
ImageView imageView1 = (ImageView) findViewById(R.id.imageview1);
imageView1.getLayoutParams().width=(int) (500.0*width_proc);
imageView1.requestLayout();
imageView1.invalidate();
TextView textView1 = (TextView) findViewById(R.id.textview1);
textView1.setText( " " + imageView1.getHeight() + " " + imageView1.getWidth() );
.......
}

Android : How to set TextViews positions depending on other ones programatically?

I want to put elements in my view depending on the position of the other ones. Let me explain : First, I have two textviews and I've put successfully the second (villeOffre) one under the first one (titreOffre) :
titreOffre = (TextView) findViewById(R.id.offreTitre);
titreOffre.setText(capitalizedString(offre.getTitle()));
villeOffre = (TextView) findViewById(R.id.offreVille);
villeOffre.setText(offre.getLocality());
infos = (TextView) findViewById(R.id.infos);
ViewTreeObserver vto = titreOffre.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener(
{
#Override
public void onGlobalLayout()
{
FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) villeOffre.getLayoutParams();
params.setMargins(15,titreOffre.getBottom()+12,15,0);
villeOffre.setLayoutParams(params);
titreOffre.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
});
This works perfectly, but now I want to put a third textview (infos) which is depending on villeOffre position. How to do that ?
Thanks a lot.
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
rr = new RelativeLayout(this);
b1 = new Button(this);
b1.setId(R.id.Button01);
recent = b1;
b1.setText("Click me");
rr.addView(b1);
setContentView(rr);
b1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
tv1 = new TextView(can.this);
tv1.setId((int)System.currentTimeMillis());
lp = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
lp.addRule(RelativeLayout.BELOW, recent.getId());
tv1.setText("Time: "+System.currentTimeMillis());
rr.addView(tv1, lp);
recent = tv1;
}
});
}

Seekbar creating EditTexts and then getting entries for further use

This code creates a seekbar and makes the seekbar create as many EditText fields as the slider is at / remove ones that would be too much. This code is in OnActivityCreated
final LinearLayout linearLayout = (LinearLayout) getActivity()
.findViewById(R.id.npv_calcfields);
EditText editText = new EditText(getActivity());
editText.setId(i);
editText.setLayoutParams(new LayoutParams(
LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
SeekBar bar = (SeekBar) getActivity().findViewById(R.id.npv_seekbar);
final TextView selection = (TextView) getActivity()
.findViewById(R.id.npv_selected);
bar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
public void onProgressChanged(SeekBar seekbar, int progress,
boolean fromUser) {
selection.setText("You have selected " + progress + " periods.");
if (progress == 0) {
String normalstring = getActivity().getResources()
.getString(R.string.npv1);
selection.setText(normalstring);
}
if (i > progress) {
while (i > progress) {
i--;
EditText editText = (EditText) getActivity()
.findViewById(i);
linearLayout.removeView(editText);
}
} else {
while (i < progress) {
EditText editText = new EditText(getActivity());
editText.setId(i);
editText.setLayoutParams(new LayoutParams(
LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT));
linearLayout.addView(editText);
editText.setHint("Cash Flow " + i);
i++;
}
}
}
public void onStopTrackingTouch(SeekBar arg0) {
}
public void onStartTrackingTouch(SeekBar arg0) {
}
});
This code is in the general class area:
int i = 0;
EditText r = (EditText) getActivity().findViewById(R.id.npv_rate);
Button calc = (Button) getActivity().findViewById(R.id.npv_calc);
EditText[] DynamicField = new EditText[16];
Now I want users to input numbers into those edittext fields and then I want to do some math on them: Entry / (Math.pow(1+r, i) with i beeing the id of the field. The first entry should therefore be calculated as this: entry/(1+r)^0. This is what I tried but it doesn't work. It just crashes on startup.
calc.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
Double r1 = Double.parseDouble(r.getText().toString());
EditText editText = (EditText) getActivity().findViewById(i);
TextView answer = (TextView) getActivity().findViewById(R.id.npv_answer);
double[] CashFlows;
CashFlows = new double[i];
double result = 0;
CashFlows[i] = (Double.parseDouble(editText.getText()
.toString())) / (Math.pow(1 + r1, i));
for (double d : CashFlows) {
result += d;
}
answer.setText("answer is " + result);
}
});
What did I do wrong? by the way only the last code segment isnt working. if i comment that out it all works fine i tested it :) just dosent do anything obviuosly :)
ok a little background on the errorlog that you can see here: http://pastebin.com/G8iX6Pkm
EDIT: the entire class file can be seen here: http://pastebin.com/dxA91dst, the entire project can be found here: https://github.com/killerpixler/Android-Financial-Calculator.git
the class file is a fragment that gets loaded in a DetailsActivity when somebody clicks on a listitem from the Main activity. Like i said the error has to be in the button listener because it was working before i added it.
That NullPointerException comes from the fact that you initialize your Views using the getActivity() method where you declare them as fields in the F_NPV class. The method getActivity() method will return a valid Activity reference after the callback onAttach() is called, so the way you initialize the views will not work as, at that moment(when the fields of the Fragment class are initialized) the method getActivity will return null, no valid reference. The correct way to do that initialization is doing it in the onActivityCreated callback:
EditText r;
Button calc;
//...
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
r = (EditText) getActivity().findViewById(R.id.npv_rate);
calc = (Button) getActivity().findViewById(R.id.npv_calc);
//...
Also, if I may, some suggestions regarding your code:
You're doing some double's parsing from Strings and it may be a good idea to check the input so you don't throw a NumberFormatException. For example, if the user creates some EditTexts and then clicks the calculate Button(I know, it sounds silly, but there are chances the user will do it(I did it for example)), you'll throw a NumberFormatException as you try to parse an empty String. Instead make a little check:
public void onClick(View arg0) {
Double r1 = Double.parseDouble((r.getText().toString())
.equals("") ? "0" : r.getText().toString());
EditText editText = (EditText) getActivity().findViewById(i);
TextView answer = (TextView) getActivity().findViewById(R.id.npv_answer);
double[] CashFlows;
CashFlows = new double[i];
double result = 0;
String tmp = editText.getText().toString();
CashFlows[i] = (Double.parseDouble(tmp.equals("") ? "0" : tmp))
/ (Math.pow(1 + r1, i));
//...
Also, even if you have correct values in the EditText the above code will throw a NullPointerException, as the editText variable will be null. The reason for this is in the while loops that you used to create the fields. For example, if the user moves the SeekBar to 3 than the while loop will run 3 times, each time incrementing the i value. So i will be 0, 1, 2, so far correct but because you increment i each time the final i will be 4. Now in the onClick method you'll look for an EditText with the id i, but as there is no EditText in the layout with the id 4, the view will be null.
Also, try to give your classes better names, you may know very well what they mean but you could be making things worse for someone that reads your code(like F_PNV, F_PV etc).
Code for the onActivityCreated method. This should solve what you're trying to do(if I understand what you want):
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
r = (EditText) getActivity().findViewById(R.id.npv_rate);
calc = (Button) getActivity().findViewById(R.id.npv_calc);
final LinearLayout linearLayout = (LinearLayout) getActivity()
.findViewById(R.id.npv_calcfields);
SeekBar bar = (SeekBar) getActivity().findViewById(R.id.npv_seekbar);
final TextView selection = (TextView) getActivity().findViewById(
R.id.npv_selected);
bar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
public void onProgressChanged(SeekBar seekbar, int progress,
boolean fromUser) {
selection
.setText("You have selected " + progress + " periods.");
if (progress == 0) {
String normalstring = getActivity().getResources()
.getString(R.string.npv1);
selection.setText(normalstring);
linearLayout.removeAllViews(); // the progress is 0 so
// remove all the views that
// are currently present
} else {
int currentChilds = linearLayout.getChildCount();
if (currentChilds < progress) {
while (currentChilds != progress) {
EditText editText = new EditText(getActivity());
editText.setLayoutParams(new LayoutParams(
LayoutParams.FILL_PARENT,
LayoutParams.WRAP_CONTENT));
linearLayout.addView(editText);
currentChilds++;
}
} else if (currentChilds > progress) {
while (currentChilds != progress) {
linearLayout.removeViewAt(linearLayout
.getChildCount() - 1);
currentChilds--;
}
}
}
}
public void onStopTrackingTouch(SeekBar arg0) {
}
public void onStartTrackingTouch(SeekBar arg0) {
}
});
calc.setOnClickListener(new OnClickListener() {
public void onClick(View view) {
Double r1 = Double.parseDouble((r.getText().toString())
.equals("") ? "0" : r.getText().toString());
TextView answer = (TextView) getActivity().findViewById(
R.id.npv_answer);
final LinearLayout linearLayout = (LinearLayout) getActivity()
.findViewById(R.id.npv_calcfields);
int size = linearLayout.getChildCount();
double[] CashFlows = new double[size];
double result = 0;
for (int i = 0; i < size; i++) {
EditText editText = (EditText) linearLayout.getChildAt(i);
String tmp = editText.getText().toString();
CashFlows[i] = (Double.parseDouble(tmp.equals("") ? "0"
: tmp)) / (Math.pow(1 + r1, i));
}
for (double d : CashFlows) {
result += d;
}
answer.setText("answer is " + result);
}
});
}

Categories

Resources