Making onCreate method look more organized - android

I have a lot of Widgets in my MainActivity, and they all have to be initalized. But when I initialize them all in the OnCreate method, the OnCreate method doesn't look organized anymore. So should I initialize them in another method in my MainActivity?

Absolutely...
Your code must be readable, not everyone think of it..!! :(
Take an example as below...
ublic class ActHome extends AppCompatActivity implements View.OnClickListener {
RelativeLayout layoutToBeHidden;
TextView tvName;
Button btnOk;
#Override
protected void onCreate(Bundle savedInstanceState) {
// do the preprocessing here
setContentView(R.layout.activity_home);
initialize();
populate();
}
private void initialize() {
// bind all your view from xml here
layoutToBeHidden = (RelativeLayout) findViewById(R.id.LayoutToBeHiddenActHome);
tvName = (RelativeLayout) findViewById(R.id.tvNameActHome);
btnOk = (RelativeLayout) findViewById(R.id.btnOkActHome);
//then set all the listeners etc.
btnOk.setOnClickListener(this);
}
private void populate() {
// populate the data here e.g. from database etc.
// and bind this data to the view etc.
String name = "android";
tvName.setText(name);
}
#Override
public void onClick(View v) {
Toast.makeText(context, "OK clicked", Toast.LENGTH_SHORT).show();
}

Yes, You can use a framework like Butter Knife to reduce code. http://jakewharton.github.io/butterknife/

You can use RoboGuice library to make your onCreate() more readable.
RoboGuice 3 slims down your application code. Less code means fewer opportunities for bugs. It also makes your code easier to follow -- no longer is your code littered with the mechanics of the Android platform, but now it can focus on the actual logic unique to your application.
To give you an idea, take a look at this simple example of a typical Android activity:
class AndroidWay extends Activity {
TextView name;
ImageView thumbnail;
LocationManager loc;
Drawable icon;
String myName;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
name = (TextView) findViewById(R.id.name);
thumbnail = (ImageView) findViewById(R.id.thumbnail);
loc = (LocationManager) getSystemService(Activity.LOCATION_SERVICE);
icon = getResources().getDrawable(R.drawable.icon);
myName = getString(R.string.app_name);
name.setText( "Hello, " + myName );
}
}
This example is 19 lines of code. If you're trying to read through onCreate(), you have to skip over 5 lines of boilerplate initialization to find the only one that really matters: name.setText(). And complex activities can end up with a lot more of this sort of initialization code.
Compare this to the same app, written using RoboGuice:
#ContentView(R.layout.main)
class RoboWay extends RoboActivity {
#InjectView(R.id.name) TextView name;
#InjectView(R.id.thumbnail) ImageView thumbnail;
#InjectResource(R.drawable.icon) Drawable icon;
#InjectResource(R.string.app_name) String myName;
#Inject LocationManager loc;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
name.setText( "Hello, " + myName );
}
}
In this example, onCreate() is much easier to take in at a glance.
RoboGuice's goal is to make your code be about your app, rather than be about all the initialization and lifecycle code you typically have to maintain in Android.
I hope it helps!

Related

Set TextView text to what is returned from function in another class

I'm new to android and I am making an app as part of an assignment, and can't get this function to return a value - the app closes and I get an error message: "Unfortunately, APP has stopped".
I have two classes, one is the MainActivity and one is a class that I am wanting to use to do arithmetic, and they are:
import com.calc.Calculation;
public class MainActivity extends Activity {
private Calculation util;
calculate = (Button) findViewById(R.id.btnCalc);
private TextView tvMultiply;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvMultiply = (TextView) findViewById(R.id.tvMult);
}
btnCalc.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
tvMiltiply.setText(String.valueOf(util.CalculateMult(4,6)));
}
});
}
and
package com.calc;
public class Calculation{
public int CalculateMult(int numOne, int numTwo)
{
return numOne * numTwo;
}
}
I've tried a few alternatives but to no avail. It's going to be something simple that I am not doing quite right.
Any help appreciated.
Thanks
You need to create instance to the class before acccessing the member.
private Calculation util = new Calculation()
Else make the method in the class as static and access without creating instance.
This would be done by defining the class as:
package com.calc;
public class Calculation{
public static int CalculateMult(int numOne, int numTwo)
{
return numOne * numTwo;
}
}
and calling the method as:
Calculation.CalculateMult(4,6)
You should move the line
calculate = (Button) findViewById(R.id.btnCalc);
to the onCreate() function after you have set the content view. You should also move the assignment of the onClickListener to your button to the onCreate() method.
Finally, you should initialize your Calculation object by using the new operator in onCreate(), i.e:
util = new Calculation();

Android Presentation Class - How to make changes on the Presentation View dynamically

My presentation is working finally. I have one main activity for my first screen and one Presentation for my second Screen.
My problem is, that I can't change the content on my presentation view.
Why can't I change a TextView after the presentation is shown on the second screen?
Calling the method changeText("Test123") in the MainActivity crashes my app.
public class MainActivity extends Activity {
private PresentationActivity presentationActivity;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// init Presentation Class
DisplayManager displayManager = (DisplayManager) this.getSystemService(Context.DISPLAY_SERVICE);
Display[] presentationDisplays = displayManager.getDisplays(DisplayManager.DISPLAY_CATEGORY_PRESENTATION);
if (presentationDisplays.length > 0) {
// If there is more than one suitable presentation display, then we could consider
// giving the user a choice. For this example, we simply choose the first display
// which is the one the system recommends as the preferred presentation display.
Display display = presentationDisplays[0];
PresentationActivity presentation = new PresentationActivity(this, display);
presentation.show();
this.presentationActivity = presentation;
}
}
public void changeText (String s) {
this.presentationActivity.setText(s);
}
}
public class PresentationActivity extends Presentation {
private TextView text;
private PresentationActivity presentation;
public PresentationActivity(Context outerContext, Display display) {
super(outerContext, display);
// TODO Auto-generated constructor stub
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_presentation);
TextView text = (TextView) findViewById(R.id.textView1);
this.text = text;
// works fine:
text.setText("test");
}
public void setText(String s){
// error
this.text.setText(s);
}
Well, I looked in the LogCat.
The exception was:
E/AndroidRuntime(13950): android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
The code in my MainActivity runs on another thread. To do UI work from here I need to use runOnUiThread. This solution I found in this answer.
My changeText methode looks like this now:
public void changeText (String s) {
runOnUiThread(new Runnable() {
public void run() {
presentationActivity.setImageView(position);
}
});
}
Thanks for the help! Now I know how to use LogCat for things like that.
You got this issue because the context of presentation is different from that of the containing Activity:
A Presentation is associated with the target Display at creation time
and configures its context and resource configuration according to the
display's metrics.
Notably, the Context of a presentation is different from the context
of its containing Activity. It is important to inflate the layout of a
presentation and load other resources using the presentation's own
context to ensure that assets of the correct size and density for the
target display are loaded.
Hope this will justify your mentioned solution as well.

How do I save the content view of my activity?

Alright so in my activity i changed my content view from one to another as you can see. so i was wondering how to save the content view that was there last when my activity was closed.
public class Levels extends Activity{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setTheme(android.R.style.Theme_NoTitleBar_Fullscreen);
setContentView(R.layout.levels);
final EditText anstext1 = (EditText) findViewById(R.id.anstext1);
Button button1 = (Button) findViewById(R.id.button1);
button1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String result = anstext1.getText().toString();
if(result.equals("they"))
setContentView(R.layout.social);
else
Toast.makeText(getApplicationContext(), "Wrong", Toast.LENGTH_LONG).show();
}
});
}
}
setContentView
You should call this method only once in the Activity lifecycle.
Saving State
Most of the time you will save your models using onSaveInstanceState and restore them using the bundles generated from that method. Activity, Fragment and Views have these kind of methods build in.
Persisting state
If you are required to use the data for a longer period than the current app lifecycle you can use one of the following mechanisms:
SharedPreferences
SQL-lite DB
File I/O
Create a variable that has the type of R.layout.levels. Assuming R.layout.levels is a RelativeLayout: RelativeLayout rl;
Initialize it like this:
rl = (RelativeLayout) getLayoutInflater().inflate(R.layout.levels,null);
setContentView (rl);
If you want to save the variable for when the activity is destroyed you can put it in a custom Application class and retrieve it from there. You find here how to do it at "maintaining global state" : http://www.intridea.com/blog/2011/5/24/how-to-use-application-object-of-android
I don't know if it is good or bad to do this, but it could be a solution for what you're asking.

pass UI Controls from activity to a class

I stuck at this issue many times and I passed the problem in different ways and I'm not sure that I made it in the right way.
I simplified the problem in a the following example. I know that I can pass only the data to the class but I do want to pass the editText cause I have this problem with more difficult UI controls.
mainactivity.java
public class mainactivity extends Activity {
public EditText clickEditText;
int count =0;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
newTxt();
}
public void newTxt() {
txt = new MyText(context);
txt.updateTextEdit("Main Activity");
}
}
myText.java
public class MyText
{
private Context _context;
// constructor
public MyText(Context context)
{
_context = context;
}
public void updateTextEdit(String str)
{
private EditText strEditText;
strEditText= (EditText)findViewById(_context.R.id.editTextClick); // ????
strEditText.setText(str + " and myTxt");
}
}
if you could explain me how to fix the updateTextEdit function. i passed the context of the main activity. How can I change the editText? Thank you very much!!!
If you really want to do this this way, you need to save a reference to Activity, not Context. Like this:
public class MyText
{
private Activity _activity;
// constructor
public MyText(Activity activity)
{
_activity= activity;
}
public void updateTextEdit(String str)
{
private EditText strEditText;
strEditText= (EditText)activity.findViewById(R.id.editTextClick);
strEditText.setText(str + " and myTxt");
}
}
and in newTxt() you will need to change:
txt = new MyText(context);
to:
txt = new MyText(this);
But wouldn't it be easier to just put this method inside your activity? Why do you want it in another class? If it really needs to be in another class, you could make that class an inner class of your activity and you would still have access to the activity's methods and member variables.
There's a similar question here
How to access Activity UI from my class?
You didn't say how you obtained the context, you should use this and get the mainactivity in the other class. not context.
then you can call runOnUIThread to perform UI updates.

why am i getting this error?? Syntax error on token "void", # expected android programming

please help me with the following code...
i am trying to make an android application and i get an error in the code when i try to create a function inside onCreate..
the need to create a function is to access buttons, labels and textboxes....
here goes my code
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final EditText player = (EditText)findViewById(R.id.player);
final TextView plrlbl1 = (TextView)findViewById(R.id.textView1);
final ImageButton imageButton1 = (ImageButton)findViewById(R.id.imageButton1);
final ImageButton imageButton2 = (ImageButton)findViewById(R.id.imageButton2);
public void thisfunction()
{
}
}
please help me create a function inside of oncreate...
help appreciated
public void thisfunction()
{
}
you declare the thisfunction() inside the onCreate(). You should declare outside the onCreate. If you are having this kind of issue I recommend you to read a basic programming book.
please help me create a function inside of oncreate...
You can't, Java doesn't allow it. You have to declare it outside of onCreate().
The correct setup is something like this
public class MyActivity extended Activity {
private TextView myTextView;
#Override
public void onCreate (Bundle savedInstanceState) {
super.onCreate () ;
setContentView(R.layout.main) ;
myTextView = (TextView) findViewById (R.id.textView1) ;
myNewMethod() ;
}
private void myNewMethod () {
myTextView.setText("Hello world") ;
}
}

Categories

Resources