Android generate new objects from onClick - android

I try to develop a simple Android App with one Button which generates new TextViews on each click.
import android.app.Activity;
import android.os.Bundle;
import android.text.Layout;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class CreateTV extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button mCreate = (Button)findViewById(R.id.btnCreate);
mCreate.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
((Button) v).setText("Clicked");
TextView mTV1 = new TextView(this);
}
});
}
}
My code is wrong because of:
TextView mTV1 = new TextView(this);
I could find some similar examples, which generate objects programmatically in onCreate(). But I want to generate and modify new objects in onClick().
Would anybody please help?

Change
TextView mTV1 = new TextView(this);
to
TextView mTV1 = new TextView(CreateTV.this);

Views can only be instantiated with a context as parameter
As you can see in the documentation a TextView needs the context to be created. TextView(Context context)
Since you are trying to create a TextView inside a ClickListener you can not use this as a reference to a Context-extending object.
As McAdam331 pointed out, use new TextView(getActivity), this works because Activity extends Context.

In addition to change TextView mTV1 = new TextView(this); to TextView mTV1 = new TextView(CreateTV.this);, you must add the TextView within a view like the following:
import android.app.Activity;
import android.os.Bundle;
import android.text.Layout;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class CreateTV extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button mCreate = (Button)findViewById(R.id.btnCreate);
mCreate.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
((Button) v).setText("Clicked");
TextView mTV1 = new TextView(CreateTV.this);
addContentView(mTV1);
}
});
}
}

I would prefer adding a Context, setting it to final and then call the Textview using the Context.
Example:
public class CreateTV extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button mCreate = (Button)findViewById(R.id.btnCreate);
final Context mContext = this;
mCreate.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
((Button) v).setText("Clicked");
TextView mTV1 = new TextView(mContext);
addContentView(mTV1);
}
});
}
}
If you want to use the Context outside the onCreate method (and within Listeners) you can define a Context.
private Context context;
public void onCreate(....) {
this.context = this;
}
private void aMethod() {
context....
}
Theres another way doing such cool stuff. Create a Class and extends it by Application.
public class MainApplication extends Application {
public static Context getContext() { return this; }
}
Then add the MainApplication to your Manifest.
<application
android:name=".MainApplication"
>
and access it from everywhere with MainApplication.getContext();

Related

string array changing onClick

I wish to have questions that change to the next question in the sequence onClick but I'm having trouble creating the array of questions and writing the onClick code for that portion.
*Too add more context to the app it will be a questionaire app with a question above an editText field and the users inputs will show up in its respective box at the top of the screen.
package com.example.greg;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
public class menu extends Activity {
Button mButton;
EditText mEdit;
int questionNumber = 0;
String [] questions;
int numberOfQuestions = 2;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mButton = (Button)findViewById(R.id.button);
mEdit = (EditText)findViewById(R.id.userAnswereditText);
questions=new String[numberOfQuestions];
questions[0]="This is first question?";
questions[1]="This is second question?";
final TextView [] myTexts = new TextView[2];
myTexts[0]=(TextView)findViewById(R.id.varATextView);
myTexts[1]=(TextView)findViewById(R.id.varBTextView);
mButton.setOnClickListener(
new View.OnClickListener()
{
public void onClick(View view)
{
myTexts[questionNumber].setText(mEdit.getText().toString());
mEdit.setText(null);
questionNumber++;
if(questionNumber < numberOfQuestions)
questionTextViewHolder.setText(questions[questionNumber]);
else
Toast.makeText(menu.this,"No more questions!",Toast.LENGTH_LONG).show();
}
});
}
#Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
}
}

Accessed from within inner Class

I am very new to Android programming and have a little problem.
The Error is:
Variable 'Demo_Button' is accessed from within inner class. Needs to declared final.
What i tried:
changed Demo_button.setImageResource(R.drawable.pressed); to final Demo_button.setImageResource(R.drawable.pressed);
package com.iklikla.eightgame;
import android.os.Bundle;
import android.app.Activity;
import android.view.View;
import android.widget.ImageButton;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ImageButton Demo_button = (ImageButton)findViewById(R.id.imageButton);
Demo_button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Demo_button.setImageResource(R.drawable.pressed);
}
});
}
}
A couple options here
First, I would declare it as a member variable then it will work
public class MainActivity extends Activity {
ImageButton Demo_button;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Demo_button = (ImageButton)findViewById(R.id.imageButton);
Second, since you are changing the View being clicked you can access it that way
emo_button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
ImageButton btn = (ImageButton)v; // cast the View to an ImageButton
btn.setImageResource(R.drawable.pressed);
}
});
Not related but will give you an error at runtime with the current code, you need to inflate a layout before trying to initialize that Button (most likely with setContentView()). So using my first example it would look something like
public class MainActivity extends Activity {
ImageButton Demo_button;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_layout); // where my_layout is the name of your layout
// file containing the Button without the xml extension
Demo_button = (ImageButton)findViewById(R.id.imageButton);

ListView: Null pointer exception

Good day. I'm having some issues with my android project specifically listview. I tried searching for other information here in this site, and implemented some of the answers. However, it is still not working.
The error specifically is
NullPointerException at line 76 at MainActivity
Here is the code of my MainActivity
import java.util.ArrayList;
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
public class MainActivity extends Activity {
final ArrayList<String> studentName = new ArrayList<String>();
ArrayAdapter<String> aa;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView myList = (ListView) findViewById(R.id.listName);
aa = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, studentName);
myList.setAdapter(aa);
//droid.R.id.list;
//add
Button bAdd = (Button) findViewById(R.id.addstudent);
bAdd.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
startActivity(new Intent("android.intent.action.ADDSTUDENTS"));
}
});
//edit
Button bEdit = (Button) findViewById(R.id.editstudent);
bEdit.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View x) {
startActivity(new Intent("android.intent.action.EDITSTUDENTS"));
}
});
//edit
Button bDelete = (Button) findViewById(R.id.deletestudent);
bDelete.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View x) {
startActivity(new Intent("android.intent.action.DELETESTUDENTS"));
}
});
}
public ArrayList<String> getArray(){
return studentName;
}
public void notifyArray(){
aa.notifyDataSetChanged();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
and line 76 by the way is
aa.notifyDataSetChanged();
Here is my code for the AddStudents class
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
public class AddStudents extends Activity{
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.add_student);
Button bAddStudents = (Button) findViewById(R.id.add);
final EditText et = (EditText) findViewById(R.id.student_name);
bAddStudents.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
MainActivity as = new MainActivity();
as.getArray().add(et.getText().toString());
as.notifyArray();
finish();
}
});
Button bBack = (Button) findViewById(R.id.backadd);
bBack.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
finish();
}
});
}
}
and the xml part with the list view is
<ListView
android:id="#+id/listName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1" >
</ListView>
I hope you can help me cause I want to also learn what my mistakes are. I can add other information if you want.
In your AddStudents class, you're calling notifyArray() right after you instantiated MainActivity. MainActivity.onCreate() will not be called just by instantiating it.
Instantiating your MainActivity there is probably not what you want anyway (because that object will be disposed directly after the onClick handler is done).
What you want instead is to access the existing instance of MainActivity. For that, add a reference to the current instance to a static member of your MainActivity class, e.g.
public class MainActivity extends Activity {
public static MainActivity activity;
#Override
protected void onCreate(Bundle savedInstanceState) {
activity = this;
}
}
Then in your AddStudent class access it via
MainActivity.activity.notifyArray()
This is not the most beautiful way to solve your issue, but it works as long as you can be sure to only have one MainActivity instance. (If not, you could make the array itself static; or create a Singleton wrapper class for it.)
notifyArray() is being called before onCreate.
Try calling getArray().add(et.getText().toString()); and notifyArray(); inside onResume() of MainActivity and NOT from AddStudentActivity( not recommended!)
So onResume() you would ideally want to add a new student to the list, so in your case, you can retrieve the student name using a common sharable object like a hashtable or somethiing similar, make it a singleton, and use it from anywhere in the applciation
The common class may go something like:
class CommonHashtable{
private static Hashtable<String, Object> commonHashtable = null;
public static getInstance(){
if(commonHashtable == null)
commonHashtable = new Hashtable<String, Object>();
return commonHashtable;
}
on getInstance(), it returns a commonHashtable which can be used to store values temporarily!
so, add this on addbutton click event
Hashtable hash = CommonHashtable.getInstance();
hash.put("NEW_STUDENT_NAME", et.getText().toString());
and add this in you onResume() of MainActivity
Hashtable hash = CommonHashtable.getInstance();
Object studentName = (String) hash.get("NEW_STUDENT_NAME");
if(studentName != null){
notifyArray();
}

I can't setText() in another class in android

I have a TextView with the id android:id="#+id/yazi", and I have a button that has build in android:OnClick="gonderB"
and I can complie this code:
package com.seri.bir;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
public class MainActivity extends Activity {
Bilmez b;
TextView t;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
b = new Bilmez();
t = (TextView) findViewById(R.id.yazi);
}
public void gonderB (View v,TextView t,Bilmez b){
String s = " ..."+this;
b.yaziYaz(v,s,t);
}
}
class Bilmez {
public void yaziYaz(View v,String s,TextView t){
t.setText(s);
}
}
However I have an error.
Can I setText in another class?
You can overwrite onClick of the activity. Avoid the using of the android:OnClick="gonderB" line in the xml file. I think it is better to implement the onClickListener and attach it to View Objects within your code.
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity implements OnClickListener {
Bilmez b;
TextView t;
Button bt;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
b = new Bilmez();
t = (TextView) findViewById(R.id.yazi);
Button bt = (Button) findViewById(R.id.btn);
bt.setOnClickListener(this);
}
#Override
public void onClick(View clickedView) {
switch (clickedView.getId()) {
case R.id.btn:
String s = "...." + this;
b.changeText(t,s);
break;
}} //end of main class }
In the changeText method you change the text of the TextView. This method can if be placed in another class if you like that.
class Bilmez {
public void changeText(TextView t, String s){
t.setText(s);
}
}
Perhaps what you are experiencing is a need to run the function on the UI thread?
public void yaziYaz(View v,final String s,final TextView t) {
runOnUiThread(new Runnable() {
public void run() {
t.setText(s);
}
});
}
i think you should do that:
public void gonderB (new View v,TextView t,Bilmez b){
String s = " ..."+this;
b.yaziYaz(v,s,t);
}

Android: Custom Dialog with Data from bundle

i want to put some string of a bundle into an custom dialog. So far i figured out Dialog doesnt handle bundles. I tried to create an onCreate Method with getIntent().getExtras(), but it doesnt work.
Can someone give me an advise?
package com.droidfish.apps.acli;
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class ShowDetails extends Activity {
TextView tvShowDetailsContent1, tvShowDetailsContent2,
tvShowDetailsContent3;
public String sDetailText1, sDetailText2, sDetailText3;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
/** Display Custom Dialog */
// CustomizeDialog customizeDialog = new CustomizeDialog(this);
CustomizeDialog customizeDialog = new CustomizeDialog(this);
tvShowDetailsContent1 = (TextView) findViewById(R.id.tvShowDetailText1);
tvShowDetailsContent2 = (TextView) findViewById(R.id.tvShowDetailText2);
tvShowDetailsContent3 = (TextView) findViewById(R.id.tvShowDetailText3);
savedInstanceState = this.getIntent().getExtras();
sDetailText1 = savedInstanceState.getString("param1");
sDetailText2 = savedInstanceState.getString("param2");
sDetailText3 = savedInstanceState.getString("param3");
tvShowDetailsContent1.setText(sDetailText1);
tvShowDetailsContent2.setText(sDetailText2);
tvShowDetailsContent3.setText(sDetailText3);
customizeDialog.show();
}
class CustomizeDialog extends Dialog implements OnClickListener {
Button okButton;
ShowDetails sh = new ShowDetails();
public CustomizeDialog(Context context) {
super(context);
/** 'Window.FEATURE_NO_TITLE' - Used to hide the title */
requestWindowFeature(Window.FEATURE_NO_TITLE);
/** Design the dialog in main.xml file */
setContentView(R.layout.showdetails);
okButton = (Button) findViewById(R.id.bOkButton);
okButton.setOnClickListener(this);
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (v == okButton)
dismiss();
}
}
}
You can implement your own constructor for the dialog that accepts a bundle
public CustomizeDialog(Context context, Bundle bundle) {
super(context);
/** 'Window.FEATURE_NO_TITLE' - Used to hide the title */
requestWindowFeature(Window.FEATURE_NO_TITLE);
/** Design the dialog in main.xml file */
setContentView(R.layout.showdetails);
//do whatever with your bundle here
okButton = (Button) findViewById(R.id.bOkButton);
okButton.setOnClickListener(this);
}
Then in your onCreate you can call
CustomizeDialog customizeDialog = new CustomizeDialog(this, getIntent().getExtras());
Don't forget to check if your bundle is null when creating the dialog

Categories

Resources