TextView failure - android

I'm programming my first android app.
I want to set text on a TextView.
(I already searched here and found out, how to do it...But it still don't work)
Do you know, what the problem is?
This is my Java code.
package com.example.randomcraps;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.widget.TextView;
import com.example.*;
public class MainActivity extends Activity {
TextView text = (TextView) findViewById(R.layout.number);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public void getRandomNumber(){
int i;
double savePoint;
savePoint = Math.random();
savePoint = savePoint*100+1;
i = (int)savePoint;
text.setText(i);
}
}
This is my XML Code
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_marginTop="26dp"
android:text="#string/Button1"
android:onClick="getRandomNumber" />
<TextView
android:id="#+id/number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="#string/RandomNumber" />
</RelativeLayout>

Change to
TextView text;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
text = (TextView) findViewById(R.id.number); // id of textview in activity_main.xml
}
findViewById looks for a view with the id mentioned in the current inflated layout. So you need to set layout to the activity and then initialize your views.
Also change
text.setText(i);
// looks for a resource with the id mentioned if not found you get ResourceNotFoundException
To
text.setText(String.valueOf(i));
// int i; i is an int value. Use String.valueOf(intvalue)
Edit:
Your method signature is different. It should be
public void getRandomNumber(View V){ // missing View as param
... //rest of the code
}
Coz you have
android:onClick="getRandomNumber"
Quoting from docs
public static final int onClick
Name of the method in this View's context to invoke when the view is clicked. This name must correspond to a public method that takes exactly one parameter of type View. For instance, if you specify android:onClick="sayHello", you must declare a public void sayHello(View v) method of your context (typically, your Activity).

Change your code to this.
TextView text;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
text = (TextView) findViewById(R.id.number);
}
Also
text.setText(String.valueOf(i));
NOTE: findViewByID finds view from content. So basically you have to use that method after you set your content.

Set text color after setText and for guarantee set the font size. Sometimes it makes the color default white.

Related

How to display rating bar stars in two lines?

I have rating bar widget in my layout and set custom style in layout.
I want to set more that 10 stars in my rating bar, i want to display rating bar stars in two line, as in single line it cut off.
Here is my layout.
<RatingBar
style="#style/starRatingBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:numStars="10"
android:stepSize="1" />
Any help is appreciated.
As far as I know, there is no way to linebreak a single RatingBar, so here is what I suggest:
Make TWO RatingBars and set their OnRatingBarChangeListeners to interact with one another.
I wrote up a quick example to show you exactly what I mean:
activity_my.xml
This would be your layout file. I used the default name when creating a new project in AS.
Use RelativeLayout.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
tools:context=".MyActivity">
<RatingBar
android:id="#+id/bar1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:numStars="10"
android:stepSize="1" />
<RatingBar
android:id="#+id/bar2"
android:layout_below="#id/bar1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:numStars="4"
android:stepSize="1" />
</RelativeLayout>
MyActivity.java
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.RatingBar;
public class MyActivity extends Activity {
private RatingBar ratingBar1;
private RatingBar ratingBar2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
setOnChangeListeners();
}
public void setOnChangeListeners(){
ratingBar1 = (RatingBar) findViewById(R.id.bar1);
ratingBar2 = (RatingBar) findViewById(R.id.bar2);
ratingBar1.setOnRatingBarChangeListener(new RatingBar.OnRatingBarChangeListener() {
#Override
public void onRatingChanged(RatingBar ratingBar, float v, boolean b) {
ratingBar2.setRating(0);
ratingBar1.setRating(v);
}
});
ratingBar2.setOnRatingBarChangeListener(new RatingBar.OnRatingBarChangeListener() {
#Override
public void onRatingChanged(RatingBar ratingBar, float v, boolean b) {
ratingBar1.setRating(10);
ratingBar2.setRating(v);
}
});
}
}
As you can see: we use a helper function: setOnChangeListeners() to initialize ratingBar1 and ratingBar2. After that we set onRatingChanged for both bars. For the first line bar made of 10 stars, we make sure ratingBar2 is set to 0. For the second bar, if it is changed, ratingBar1 must be set to 10 so it will be full.
Try it out! Hope it works for you!
Rating bar can't break in two line so add rating bar layout dynamically
int noOfStarts = 8;
int noOfRatingLine = (noOfStarts/5)+1;
LinearLayout[] linear = new LinearLayout[noOfRatingLine];
RatingBar[] ratingBarNames = new RatingBar[noOfRatingLine];
for(int i =0;i<noOfRatingLine;i++)
{
linear[i] = (LinearLayout)this.getLayoutInflater().inflate(R.layout.app_ratingbar, null);
ratingBarNames[i] = (RatingBar)linear[i].findViewById(R.id.rating);
if(noOfStarts<5){
ratingBarNames[i].setNumStars(noOfStarts);
}
else{
ratingBarNames[i].setNumStars(5);
}
ratingBarNames[i].setStepSize(1);
noOfStarts = noOfStarts-5;
ratingbarLayout.addView(linear[i]);
}
XML layout app_ratingbar.xml for inflate
<RatingBar
android:id="#+id/rating"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
</RatingBar>

Why linearlayout's size -1?

I'm trying to get linearlayout's size.
I tested as following code.
But I just get value -1 (linearlayout's width).
How to get correct size?
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/mainLayout"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Hello World, MyActivity"
/>
</LinearLayout>
package com.example.LayoutSize;
import android.app.Activity;
import android.os.Bundle;
import android.view.ViewGroup;
import android.widget.LinearLayout;
public class MyActivity extends Activity {
/**
* Called when the activity is first created.
*/
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
LinearLayout linearLayout = (LinearLayout) findViewById(R.id.mainLayout);
ViewGroup.LayoutParams layoutParams = linearLayout.getLayoutParams();
System.out.printf("linearLayout width : %d", layoutParams.width);
}
}
The reason you get -1 is because the width parameter is set to MatchParent which has a value -1.
To get the size of a layout, your should be using getWidth() or getMeasuredWidth() methods. However, these methods won't give you a meaningful answer until the view has been measured. Read about how android draws views here.
You can get the correct size, by overriding the onWindowFocusChanged() as mentioned in this thread.
Alternatively, (hacky solution), you could do this:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final LinearLayout linearLayout = (LinearLayout) findViewById(R.id.mainLayout);
linearLayout.post(new Runnable() {
#Override
public void run() {
System.out.printf("linearLayout width : %d", linearLayout.getMeasuredWidth());
}
});
}
public static final int MATCH_PARENT = -1;

Reference to TextView object from nested class

I'm new to Android programming and probably I don;t understand Java very well yet, so i got this problem with my program.
Every time I press button on my menu I get the java.lang.NullPointerException.
Is there any way to reference to this TextView object and change its text when item2 on menu is clicked?
public class MainActivity extends Activity {
TextView tv;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MainActivity.this.tv = (TextView) findViewById(R.id.tekst1);
setContentView(R.layout.activity_main);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.mymenu, menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.item2) {
MainActivity.this.tv.setText("aaa");
}
return super.onOptionsItemSelected(item);
}
}
EDIT:
mymenu xml:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="#+id/item1"
android:icon="#android:drawable/ic_menu_week"
android:title="Option 1"/>
<item
android:id="#+id/item2"
android:icon="#android:drawable/ic_menu_month"
android:title="Option 2"/>
</menu>
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<TextView
android:id="#+id/tekst1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="#string/hello_world"
tools:context=".MainActivity" />
</RelativeLayout>
You need to load the layout BEFORE retrieving the element.
Just replace
MainActivity.this.tv = (TextView) findViewById(R.id.tekst1);
setContentView(R.layout.activity_main);
By
setContentView(R.layout.activity_main);
MainActivity.this.tv = (TextView) findViewById(R.id.tekst1);
The findViewById method tries to find an element (from an ID) inside the hierarchy of the view. That's why you need to load this hierarchy (from the XML file) before! Otherwise you search in an empty hierarchy of views
You have to change your onCreate method to this:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MainActivity.this.tv = (TextView) findViewById(R.id.tekst1);
}
You have to reference your views after doing setContentView for your Activty.
By using the setContentView(int layoutResId) method android platform is creating all the view objects contained in your layout xml file provided to the setContentView(int layoutResId) method. This means that before the setContentView(int layoutResId) method is called the findViewById(int resId) method will return null for any view references in the layout, causing some potential NullpointerExceptions. To avoid these errors it's a good habit to place the setContentView(int layoutResId) method call at the very top of the onCreate() method.
Check this out : http://www.jayway.com/2009/03/26/layout-resources-in-android/

Different content same page

I have an application to display quotes one after another. The page format is same but every time just the content changes. And accordingly the buttons for previous and next pages. Is there a way to do it using xml?
See Bellow Example:
main.xml
<?xml version="1.0" encoding="utf-8"?>
<Button android:onClick="onClickNext"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Click"
/>
<TextView android:text="TextView" android:id="#+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content"></TextView>
Your ACtivity:
public class MyActivity extends Activity {
/** Called when the activity is first created. */
private TextView tv;
private String data[4];
private int i = 0;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
tv = (TextView) findViewById(r.id.extView1)
data[0] = "hello";
data[1] = "hi";
data[2] = "bye";
data[3] = "fine";
}
public void onClickNext(View v)
{
if(i<data.length)
{
tv.setText(data[i]);
i++;
}
}
}
Define your view with a text view and the two buttons, and use the setText method on the text view to change the text.
Inside your activity, you want something like this:
public void onNextButtonClicked(View view) {
TextView myView = (TextView)this.findViewById(R.id.myTextView);
myView.setText("My next text");
}
Inside your layout XML, something like this would set up the event binding:
<Button
android:id="#+id/nextButton"
android:onClick="onNextButtonClicked"
android:text="#string/next_button"/>

dynamic number of gui elements in Android?

I want to create a gui application for android where the user will be able to add or remove fields of certain type (4 different type of fields) to the application. Is there a way to do so in xml?
The only way I could figure to do so is by edditing the xml file from within the app which sounds as a bad idea for me.
Hope my question is clear.
Yotam.
Edit:
I have added a simple code for direct java implantation:
import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.view.ViewGroup;
import android.widget.TextView;
public class Leonidas extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.counter);
TextView TV = new TextView (this);
TextView UV = new TextView (this);
TV.setText("hello");
UV.setText("goof");
//setContentView(TV);
//setContentView(UV);
ViewGroup.LayoutParams lpars = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.FILL_PARENT);
this.addContentView(UV,lpars);
this.addContentView(TV, lpars);
this.setVisible(true);
}
}
Edit2:
I have searched for example and got the following working:
LayoutInflater inflater;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
inflater = LayoutInflater.from(this);
Button b = (Button) this.findViewById(R.id.alert);
b.setOnClickListener(this);
}
#Override
public void onClick(View v) {
final LinearLayout canvas = (LinearLayout)Leonidas.this.findViewById(R.id.counter_field);
final View cv = this.inflater.inflate(R.layout.counter,canvas,false);
canvas.addView(cv);
}
You can do it from within your handler too (in the implementation class).
After inflating your xml layout, you respond to some kind of user interactions.
In the handler you
either create a new View from
scratch, and specify its
layoutparams,
or inflate one using xml
After having the new view, you add it to the current (this) view, and due to its layoutparams, it will be the size, shape, color, etc. that you want.
Update:
If you'd like to add more complex views to your activity, it's better to write them in xml, and inflate them:
sample_component.xml: //inside res/layout
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:padding="0px">
<TextView android:id="#+id/servicename_status" android:paddingLeft="15px"
android:paddingRight="5px"
android:textStyle="bold" android:focusable="false" android:textSize="14px"
android:layout_marginLeft="10px" android:layout_marginRight="3px"
android:layout_width="fill_parent" android:layout_height="wrap_content" />
<TextView android:id="#+id/lastcheck" android:focusable="false"
android:textSize="14px" android:layout_width="fill_parent"
android:layout_marginLeft="10px" android:layout_marginRight="3px"
android:layout_height="wrap_content" android:layout_below="#id/servicename_status" />
<TextView android:id="#+id/duration" android:focusable="false"
android:textSize="14px" android:layout_width="fill_parent"
android:layout_marginLeft="10px" android:layout_marginRight="3px"
android:layout_height="wrap_content" android:layout_below="#id/lastcheck" />
<TextView android:id="#+id/attempt" android:focusable="false"
android:textSize="14px" android:layout_width="fill_parent"
android:layout_marginLeft="10px" android:layout_marginRight="3px"
android:layout_height="wrap_content" android:layout_below="#id/duration" />
<TextView android:id="#+id/statusinfo" android:focusable="false"
android:textSize="14px" android:layout_width="fill_parent"
android:layout_marginLeft="10px" android:layout_marginRight="3px"
android:layout_height="wrap_content" android:layout_below="#id/attempt" />
<CheckBox android:id="#+id/alert" android:focusable="false"
android:layout_alignParentRight="true" android:freezesText="false"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="5px" />
</RelativeLayout>
Inside your Leonidas activity class you have the handlers that have to respond to different user actions by adding/removing items to/from the view.
Below is a sample handler of a click event, which uses LayoutInflater, to add the sample_component.xml view to your activity:
public final class MyClickListener implements View.OnClickListener
{
private LayoutInflater inflater;
public MyClickListener()
{
inflater = LayoutInflater.from(Leonidas .this);
}
#Override
public void onClick(View v)
{
// TODO: change RelativeLayout here to whatever layout
// you'd like to add the new components to
final RelativeLayout canvas = (RelativeLayout)Leonidas.this.findViewById(R.id.my_canvas);
final View childView = inflater.inflate(R.layout.sample_component, canvas, false);
// TODO: Look up the 5 different signatures of the addView method,
// and pick that best fits your needs
canvas.addView(childView);
// check which button was pressed
switch (view.getId())
{
case R.id.btn_prev:
//handler for the prev button
break;
case R.id.btn_next:
//handler for the next button
break;
default:
break;
}
}
}
Note, that MyClickListener is implemented as an inline class within your Leonidas activity, thay's why for the context parameter it is used: this.Leonidas.
Update
The R.id.my_canvas would be the id of the view that you want to add components to. it is in your main.xml (or whatever xml you use for your Leonidas view).
If you put the MyClickListener class inside your Leonidas.java class (declare as inline class), it will recognize it.
Instead of specifying elements in the XML, you can create them dynamically and add it to the UI. This is demonstrated in the Android Hello World Tutorial here.

Categories

Resources