Android : Setvisibility to visible causes nullpointerexception on button - android

This seems to have been asked in stackoverflow a bit before with no convincing answers for most questions. anyways, i attempt again.
I have an Android App where am displaying a list where each row has an Edittext and Button component as seen below
The Edittext is non-editable when the view appears. I do this with the code below:
private void setNameAsEditable (View rowView, boolean setToEditable) {
EditText textView = (EditText) rowView
.findViewById(R.id.edittext_name);
textView.setFocusableInTouchMode(setToEditable);
textView.setFocusable(setToEditable);
ImageButton button = (ImageButton) rowView
.findViewById(R.id.button_save_name);
if ( setToEditable ) {
button.setVisibility (View.VISIBLE); // nullpointerexception here
} else {
button.setVisibility (View.GONE);
}
When I long-press, and setToEditable is true, it throws nullpointerexception in the line indicated above. it doesn't seem to find the button component. However, 'button.setVisibility (View.GONE);' is executed when setToEditable is false without any issue.
Can someone please help?

rowView appears to be your EditText while you actually want the parent view that has the button inside of it. If you call findViewById and the id doesn't exist inside of that view, it will return null.

I think issue is initialization of view control. You should initialize EditText & ImageButton at the top.
EditText textView;
ImageButton button ;
...
...
...
EditText textView = (EditText) rowView.findViewById(R.id.edittext_name);
ImageButton button = (ImageButton) rowView.findViewById(R.id.button_save_name);
And next thing is try to write your code in try & catch block so you get exact idea what is wrong and where is bug.

Related

Button to hide a TextView

I've been searching for a solution for this for a while but cannot seem to get one working. There are one or two on here about this subject but I can't seem to get them going. I'm also a novice in Android and while I've been on and off playing with it for a few years, I still understand next to nothing about what I'm writing.
Basically I've got a TextView and a button. Ideally I'd like to put some text in the TextView, press a button it's gone, press the button again and it's back.
I've narrowed it down to needing to understand what findViewById(R.id.button2) does but honestly I'm a bit lost.
I've added my button code but apologies that this is such a noob question
public void onClick(Button v){
TextView t1 = (TextView)findViewById(R.id.editText);
v.setVisibility(View.GONE);
Button button = (Button) findViewById(R.id.button2);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
TextView t1 = (TextView)findViewById(R.id.TextView);
v.setVisibility(View.GONE);
}
});
}
Your code has a couple of issues. I'm not going to give you the code because that won't really help you learn. Instead I'll explain things and let you try to figure it out or come back with more explicit questions.
You know that xml file you set using setContentView? Some of the tags in it had a property android:id="xxxx". That xxxx is the id of that view, its used so you can find that view in your code. The findViewById function walks through all the views on screen and finds a view with that id and returns it. That gives you a reference to the view so you can change it. For example, you can set its visibility, set its background color, or set an OnClickListener.
So to have a button toggle the visibility of another view, you need to be able to do the following things:
1)Find the view who's visibility you want to change
2)Figure out what its visibility currently is
3)Figure out what you want it to be (the opposite of what it currently is
4)Set that visibility
You need to write a function that does all that. Then you need to do this
1)Find the button you want to use to change the visibility
2)Tell it to call your function when its pressed.
Figure out how to do each of those steps individually, and you should be able to put it together. Good luck.
findViewById(R.id.button2) finds the view with the id button2.
You can check inside onClick whether t1 is visible or not (t1.setVisibility(View.GONE); not v.setVisibility(View.GONE);), and toggle between View.GONE and View.VISIBLE.
Remember that your findViewById() should have a real id. They are normally set on the activity_name.xml.
You are using a onClick inside a onClick. Personally I recommend setting the listener manually with setOnClickListener.
There's a lot of work for you, start with these tutorials. Keep trying and try to understand what you are doing.
Look like you need a toogle button feature, here is a piece of code.
Important: you must pay heed to #GabeSechan and #SkyDriver2500 answers.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.your_layout);
//your other code
Button button = (Button) findViewById(R.id.button2);
final TextView t1 = (TextView) findViewById(R.id.editText);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
t1.setVisibility(t1.getVisibility() == View.VISIBLE ? View.GONE : View.VISIBLE);
}
});
}
I'm not sure if the code will help you now. But just in case, here it is
final boolean[] isTvVisible = {false};
final TextView t1 = (TextView)findViewById(R.id.editText);
t1.setVisibility(View.GONE);
Button button = (Button) findViewById(R.id.button2);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if (isTvVisible[0]) {
t1.setVisibility(View.GONE);
isTvVisible[0] = false;
} else {
t1.setVisibility(View.VISIBLE);
isTvVisible[0] = true;
}
}
});

Clicking twice on a radiobutton generates illegalstateexception

I am getting an object of RadioButton by using findViewById() and then setting an `onclicklistener' for it.The code goes like :
final EditText editTextView = (EditText)findViewById(2001);
RadioButton rb = (RadioButton) findViewById(R.id.radio3);
rb.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
LinearLayout linearLayout = (LinearLayout) findViewById(R.id.editTextGroupLayout);
LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT);
editTextView.setLayoutParams(params);
editTextView.setInputType(InputType.TYPE_NUMBER_FLAG_DECIMAL| InputType.TYPE_NUMBER_FLAG_SIGNED);
editTextView.setId(2001);
linearLayout.addView(editTextView);
}
});
When i click Once on the radiobutton it works fine.But when i click it twice,it generates
java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
By clicking it twice why this exception occurs?
What i tried
I tried to remove the line final EditText editTextView = (EditText)findViewById(2001);
and add this line inside the onClick(),EditText editTextView = (EditText)findViewById(2001);.But by doing this it doesn't get executed even once.It shows exception too.
It is beacouse you got only one instance of edittext which alerady has a parent after first click. Try to remove view from parent and than place it again.
Or maybe try to show/hide it?
You should propably do something like this.
linearLayout.removeAllViews(); or linearLayout.removeView(editTextView);
...
linearLayout.addView(editTextView);

android working with Views

In my activity I have the following views
TextView player1;
TextView player2;
TextView player3;
TextView player4;
EditText player1name;
EditText player2name;
EditText player3name;
EditText player4name;
Each of the TextView's has the onclick listener applied to it. and so fires the OnClick function.
When we get to the onClick this is what i am currently doing:
#Override
public void onClick(View v) {
//the v variable is the clicked textview, in this case "player1"
//hide the textview and show the resultant edittext
v.setVisibility(View.GONE);
player1name.setVisibility(View.VISIBLE);
//set focus on edit text and when focus is lost hide it and set the textview text
player1name.requestFocus();
imm.showSoftInput(player1name, InputMethodManager.SHOW_FORCED);
player1name.setOnFocusChangeListener(new OnFocusChangeListener() {
#Override
public void onFocusChange(View y, boolean x) {
v.setVisibility(View.VISIBLE);
player1name.setVisibility(View.GONE);
imm.hideSoftInputFromWindow(player1name.getWindowToken(), 0);
String name = player1name.getText().toString();
if (name.equals("")) {
v.setText("Player Name1");
} else {
v.setText(name);
}
}
});
}
However with this solution I will need to duplicate this code and change the view names for player2 - player2name, player3 - player3name etc
i can obviously grab the clicked TextView via v, however what i cant seem to do is grab its corresponding EditText.
i had thought of doing this:
View test = v + "name";
//then i replace all references to player1name with the test variable
but it doesnt work it wants me to convert View test; into a string
any suggestions?
EDIT: made it easier to understand my question
View test = v + "name";
will give a compile error. Because "v" is not a string type. and also even if it was String, test is not. This line is pretty wrong.
There a few options to achieve what you want,
You can use hashmap
Declare a global field for hashmap
private final HashMap<Integer,EditText> map = new HashMap<Integer,EditText>();
and in onCreate method put your textview id as key, and put your edittext variables in value.
player1name = (EditText) findViewById(R.id.player1name);
map.put(R.id.textView1, player1name);
// for the rest
in onClick method
EditText e = map.get(v.getId());
Then replace them with "e"
e.requestFocus(); //example
Will you please state your problem clearly? Currently, your language is very ambiguous and I can not figure out, exactly what are you looking for. It will help us to know your problem and in turn solve it.

TextView is returning null

I have a listener that simply changes a button's text and clocks the time for the user. I also have a textview that is supposed to change to the new total amount of time worked when the user clocks out. I double checked the xml to make sure I was grabbing the right R.Id and the button in the listener is being found just not the TextView. Here is the code:
public class HoursListener implements OnClickListener{
GlobalApp appState;
Button startStopHoursButton;
TextView hoursTotalTextView;
public boolean clockedIn;
public HoursListener(Context ctx){
appState = ((GlobalApp)ctx.getApplicationContext());
}
public void onClick(View v) {
startStopHoursButton = (Button) v.findViewById(R.id.hourstogglebutton);
hoursTotalTextView = (TextView) v.findViewById(R.id.totalWorktimeTextView);
if(!clockedIn){
startStopHoursButton.setText(R.string.clockout);
appState.getCurrentCompany().getCurrentNewWeeklyTimestamp().CreateFinishTimeStamp();
clockedIn = true;
}else{
startStopHoursButton.setText(R.string.clockin);
appState.getCurrentCompany().getCurrentNewWeeklyTimestamp().CreateFinishTimeStamp();
clockedIn = false;
hoursTotalTextView.setText(appState.getCurrentCompany().getCurrentNewWeeklyTimestamp().totalTimeDoneThisWeekToString());
}
}
}
Heres the xml for the textView:
<TextView
android:id="#+id/totalWorktimeTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="#+id/textView2"
android:text=""
android:textAppearance="?android:attr/textAppearanceSmall"/>
The error is with this line:
hoursTotalTextView.setText(appState.getCurrentCompany().getCurrentNewWeeklyTimestamp().totalTimeDoneThisWeekToString());
I was thinking about just putting the code in the activity itself but I feel like I can do it this way. I want something I can call like a listener so I reduce the redundancy in my code. I have double checked that it is the hoursTotalTextView that is null. Yet the button isn't. Any ideas?
Screenshot of Eclipse (linked to full-size version) showing that the relevant values aren't null:
Presumably the onClickListener whose click you are listening to is the button? The onClick passes the View v that was clicked - i.e. the button - and the textbox is not a child of the button, so you can't find it.
If HoursListener is declared inside your activity, just do findViewById instead of v.findViewById i.e.
hoursTotalTextView = (TextView) findViewById(R.id.totalWorktimeTextView);
If not, pass the textview into the HoursListener constructor and set hoursTotalTextView there (bearing in mind this feels like it might cause memory leaks).
what is GlobalApp appState; and why you are typecasting context to GlobalApp from below line.
I think appstate will be null here.
appState = ((GlobalApp)ctx.getApplicationContext());
if GlobalApp is a class then create a object for it and then use getter and setter methods.
you need to use
startStopHoursButton = (Button) v.findViewById(R.id.hourstogglebutton);
hoursTotalTextView = (TextView) v.findViewById(R.id.totalWorktimeTextView);
some where before,can be constructor cause your setText is working on null TextView object.
Check each object in that line
if(appState.getCurrentCompany()==null)
Log.d("","getCurrentCompany is null");
if(appState.getCurrentCompany().getCurrentNewWeeklyTimestamp()==null)
Log.d("","getCurrentNewWeeklyTimestamp is null");
if(appState.getCurrentCompany().getCurrentNewWeeklyTimestamp().totalTimeDoneThisWeekToString()==null)
Log.d("","totalTimeDoneThisWeekToString is null");

editing a global variable

Hi im new to android and I have a program that has a global variable define and it works, so I can set it and get it in every activity, BUT it dosnt like to be changed in an on click listener. I made it so on the screen there is an edittext and when someone presses a button I want the edittext text to be put into the global variable. here is my code:
Button SiteButton = (Button) findViewById(R.id.SiteButton);
SiteButton.setOnClickListener(new View.OnClickListener() {
TextView textviewS = (TextView) findViewById(R.id.SiteIdT);
EditText edittextS = (EditText) findViewById(R.id.SiteIdE);
TextView textviewB = (TextView) findViewById(R.id.BusIdT);
EditText edittextB = (EditText) findViewById(R.id.BusIdE);
public void onClick(View v) {
textviewS.setText(edittextS.getText());
((Global) this.getApplication()).setgSiteId(textviewS.getText().toString());
textviewB.setText(edittextB.getText());
((Global) this.getApplication()).setgVehicleId(textviewB.getText().toString());
}
});
but the getApplication() part is showing an error. can anyone help?
You should refer to your activity this, since View.OnClickListener doesn't have such a method:
// Bad code! read below
((Global) MyActivityClassName.this.getApplication()).setgSiteId(textviewS.getText().toString());
textviewB.setText(edittextB.getText());
((Global) MyActivityClassName.this.getApplication()).setgVehicleId(textviewB.getText().toString());
By the way, how do you cast the return from getApplication() to Global? You will get a class cast exception there.

Categories

Resources