I'm making a program that when I press a button this change the background color but I have a problem with, when I change the screen orientation this change again the color to the predefined and I dont know how to solve this problem... Here is my code.
public class MainActivity extends Activity implements OnClickListener {
LinearLayout myLayout;
LinearLayout myLayout2;
// Declare UI elements
private Button firstButton, secondButton, thirdButton, fourthButton, fifthButton;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main); // Our only layout for this app is main.xml
myLayout = (LinearLayout) findViewById(R.id.myLayout);
myLayout2 = (LinearLayout) findViewById(R.id.myLayout2);
// Initialize the UI components
firstButton = (Button) findViewById(R.id.button1);
// When we creating a button and if we expect that to use for event handling we have to set the listener
firstButton.setOnClickListener(this);
secondButton = (Button) findViewById(R.id.button2);
secondButton.setOnClickListener(this);
thirdButton = (Button) findViewById(R.id.button3);
thirdButton.setOnClickListener(this);
fourthButton = (Button) findViewById(R.id.button4);
fourthButton.setOnClickListener(this);
fifthButton = (Button) findViewById(R.id.button5);
fifthButton.setOnClickListener(this);
}
}
The problem is that when the orientation is changed, the activity is restarted. There are multiple ways to fix that.
One way is to make it so that the activity won't restart when the orientation is changed. Here's how to do that:
Add android:configChanges="orientation|screenSize" to your <activity tag, which is in your AndroidManifest.xml, like so:
<activity
android:name="UserIdActivity"
android:label="#string/app_name"
android:configChanges="orientation|screenSize" />
Rastikan's answer did it slightly differently, but his way of doing it won't work for any API after API 12 (source and this too). My way above, you don't actually need to call onConfiguationChanged in your activity class.
Another way of doing it would to use onSaveInstanceState(Bundle savedInstanceState) like Rastikan did.
Another way of doing it would be to let the activity restart itself, but then using the onResume() method to change the background colour, if necessary, when the activity is restarted. Like this:
public boolean changeColor = false;
// set changeColor to be true whenever you change the background colour
public void onResume()
{
if (changeColor) {
// change the background color
}
}
Here is a short/alternate version assuming a view (view1) of some sort.
import android.os.Bundle;
import android.app.Activity;
import android.graphics.Color;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity {
private static final int DEFAULT_COLOR = Color.WHITE;
private int myColor;
// Assuming a 'view' of some sort
private View myView;
// Declare UI elements
private Button firstButton;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); // Our only layout for this app
// is main.xml
myView = (View) findViewById( R.id.view1 );
firstButton = (Button) findViewById( R.id.button1 );
Log.i("MainActivity", "onCreate"
+ ((null == savedInstanceState) ? "(null)"
: "(savedInstanceState)"));
if (savedInstanceState != null) {
myColor = savedInstanceState.getInt("COLOR");
} else {
myColor = DEFAULT_COLOR;
}
myView.setBackgroundColor(myColor);
firstButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (myColor == Color.WHITE)
myColor = Color.BLACK;
else if (myColor == Color.BLACK)
myColor = Color.WHITE;
myView.setBackgroundColor(myColor);
}
});
}
#Override
// this method is called before android trashes and recreates your activity
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("COLOR", myColor);
}
}
Alternatively you could do it the cheap-dumb-ass way: Locking the screen. add the 'android:configChanges' attribute to your activity.
<activity
android:name="UserIdActivity"
android:label="#string/app_name"
android:configChanges="orientation" />
And implement the 'onConfigurationChanged' callback to do nothing
public void onConfigurationChanged ( Configuration newConfig)
{
}
Related
Lets say I have a few buttons and their click is handled by a common handler is there a way to define the listener once and not defining an onClick attribute for each button?
<Button android:onClick="handler" />
Perhaps parent delegation as in browsers or some interceptor .....imagine you have 50 buttons, you declare on click for each explicitly???
Yes you can do so.
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
List<Button> buttons;
ViewGroup parentView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
buttons = new ArrayList<>();
parentView = (ViewGroup) findViewById(R.id.cord);
//Replace the above line with the container view i.e.
//Replace parentView = (ViewGroup) findViewById(R.id.cord);
// With parentView = (ViewGroup) findViewById(R.id.<YOUR MAIN VIEW/PARENT CONTAINER>);
//R.id.cord is R.id.<YOUR MAIN VIEW/PARENT CONTAINER> for me because my Relative Layout
// container's name is cord.
for(int i=0; i < parentView.getChildCount(); i++) {
childView = parentView.getChildAt(i);
//The if may change there are other options try them too.
if(childView.getClass().getName().substring(35).equals("Button")){
buttons.add((Button)parentView.getChildAt(i));
}
/*
//Else part optional
//Remove comment to use
else
Log.e("Not","A Button");*/
}
for (int i =0;i<buttons.size();i++){
buttons.get(i).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//Do the work here
Log.d("Button Clicked",Integer.toString(view.getId()));
}
});
}
}
}
This is a way that you can solve your problem...
The best way: Just let your activity implement View.OnClickListener, and write your onClick method like this:
public void onClick(View v) {
final int id = v.getId();
switch (id) {
case R.id.button1:
// your code for button1 here
break;
case R.id.button2:
// your code for button2 here
break;
// even more buttons here
}
}
Then, in your XML layout file, you can set the click listeners directly using the attribute android:onClick:
<Button
android:id="#+id/button1"
android:onClick="onClick"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button 1" />
Yes, it can be achieved at the activity level programmatically. So no need to define the "onClick" attribute in XML.
You define a View.OnClickListener class. For e.g.
View.OnClickListener buttonListener = new View.OnClickListener() {
public void onClick(View v) {
// here you can define different code for different buttons
};
then you attach this listener to all your buttons on one place
final Button button = findViewById(R.id.button_id);
button.setOnClickListener(buttonListener);
Here's what I finally came to as solution it works only with touchables for instance TextView isn't a touchable:
In java:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final MainActivity activity = this;
/* Any kind of ViewGroup that is
parent of the common listener views. In the example it is the rootView */
View rootView = this.getWindow().getDecorView().getRootView();
// Buttons are touchables
ArrayList<View> touchables = rootView.getTouchables();
// Define the common on click listener for the buttons
View.OnClickListener listener = new View.OnClickListener() {
public final void onClick(View view) {
activity.onBtnClick( (Button) view );
}
};
// Iterate trough touchables and if the View is a button assign the listener
for (View v: touchables) {
// TODO: omit button if that common listener isn't meant for it
if(v instanceof Button) {
v.setOnClickListener(listener);
}
}
}
// The listener callback
protected final void onBtnClick(Button btn) {
String btnStringId = btn.getResources().getResourceEntryName(btn.getId());
}
In Kotlin:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
/* Any kind of ViewGroup that is
parent of the common listener views. In the example it is the rootView */
val rootView = window.decorView.rootView
val touchables = rootView.touchables
val listener = View.OnClickListener {
onBtnClick(it as Button)
}
touchables.forEach { if (it is Button) {
it.setOnClickListener(listener)
}}
}
protected fun onBtnClick(btn: Button) {
var btnStringId = btn.getResources().getResourceEntryName(btn.id)
}
Ok, I know there have been a lot of questions about SharedPreferences in Android asked before, and I did manage to get quite far, but since I'm kinda new to SharedPreferences I don't know the last few steps to get it to work.
In my MainActivity I have the following:
public class MainActivity extends ActionBarActivity
{
...
// Public static MainActivity so we can use findViewById from MyPrefsActivity
public static MainActivity mActivity;
#Override
protected void onCreate(Bundle savedInstanceState) {
...
mActivity = this;
}
...
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
switch(id){
case R.id.action_settings:
startActivity(new Intent(this, MyPrefsActivity.class));
return true;
}
return false;
}
}
And this is MyPrefsActivity.java:
package com.example.checkboxoptionsv2;
import android.annotation.TargetApi;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.os.Bundle;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceChangeListener;
import android.preference.PreferenceActivity;
import android.preference.PreferenceFragment;
import android.preference.PreferenceManager;
import android.view.View;
import android.widget.ImageButton;
public class MyPrefsActivity extends PreferenceActivity implements OnSharedPreferenceChangeListener
{
private static int prefs = R.xml.settings;
private ImageButton cbButton, spinnerButton, popupButton;
private final String LIST_PREFERENCE = "prefCheckboxOption";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try{
getClass().getMethod("getFragmentManager");
AddResourceApi11AndGreater();
}
catch(NoSuchMethodException e){ // Android API < 11
AddResourceApiLessThan11();
}
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
preferences.registerOnSharedPreferenceChangeListener(this);
* ListPreference listPreference = (ListPreference) findPreference(LIST_PREFERENCE);
if(listPreference.getValue() == null)
listPreference.setValue("0");
cbButton = (ImageButton) MainActivity.mActivity.findViewById(R.id.ibtnCheckbox);
spinnerButton = (ImageButton) MainActivity.mActivity.findViewById(R.id.ibtnSpinner);
popupButton = (ImageButton) MainActivity.mActivity.findViewById(R.id.ibtnPopup);
setChosenPreference(0);
}
private void setChosenPreference(int chosen_value){
// First put all Visibilities on GONE
cbButton.setVisibility(View.GONE);
spinnerButton.setVisibility(View.GONE);
popupButton.setVisibility(View.GONE);
// Then turn the chosen on VISIBLE again
switch(chosen_value){
case 0: // Multi-Click CheckBox
default:
cbButton.setVisibility(View.VISIBLE);
break;
case 1: // Dropdown CheckBox
spinnerButton.setVisibility(View.VISIBLE);
break;
case 2: // Pop-up CheckBox
popupButton.setVisibility(View.VISIBLE);
break;
}
}
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if(key.equals(LIST_PREFERENCE)){
ListPreference listPreference = (ListPreference) findPreference(key); // LIST_PREFERENCE
listPreference.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
#Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
int chosen_option = Integer.valueOf((String) newValue);
setChosenPreference(chosen_option);
return false;
}
});
}
else{
// Other settings
}
}
#SuppressWarnings("deprecation")
protected void AddResourceApiLessThan11(){
addPreferencesFromResource(prefs);
}
#TargetApi(11)
protected void AddResourceApi11AndGreater(){
* MyPreferenceFragment pf = new MyPreferenceFragment();
getFragmentManager().beginTransaction().replace(android.R.id.content, pf).commit();
}
#TargetApi(11)
public static class MyPreferenceFragment extends PreferenceFragment{
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
* addPreferencesFromResource(MyPrefsActivity.prefs); // outer class
// private members seem to be visible for inner class, and
// making it static made things so much easier
}
}
}
And the settings.xml:
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<PreferenceCategory android:title="#string/checkbox_options_title" >
<ListPreference
android:key="prefCheckboxOption"
android:title="#string/pref_checkbox_option"
android:summary="#string/checkbox_options_summary"
android:entries="#array/checkbox_options"
android:entryValues="#array/checkbox_option_values" />
</PreferenceCategory>
</PreferenceScreen>
and arrays.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="checkbox_options">
<item>CheckBox as Multi-Click</item>
<item>CheckBox as Dropdown</item>
<item>CheckBox as Pop-up</item>
</string-array>
<string-array name="checkbox_option_values">
<item>0</item>
<item>1</item>
<item>2</item>
</string-array>
</resources>
(Of course I've also included the MyPrefsActivity in the AndroidManifest.xml)
My goal is to make one of the three checkbox-option (found in the setChosenPreference method) VISIBLE, and the other two GONE, based on the preference selected in the ListPreference.
Right now the Listpreference in both the onCreate() method and onSharedPreferenceChanged() is null and giving a NullPointerException. So I set some breakpoints (see the three " * ") and the reason they are null is because the third " * " (in the static class PF) isn't called.
The addPreferencesFromResources should be called before using findPreference, otherwise it will return null. Does anyone know why during debugging I do get to the second " * " in the AddResourceApi11AndGreater() method, but I'm not getting to the third one in the MyPreferenceFragment-class onCreate method() ?.. the onCreate isn't called at all..
Also, does the rest of my code seems ok(-ish) or should I change something in order to make it work as I intended?
Thanks in advance for the responses.
TL;DR: MyPreferenceFragment instantion is created successfully, but it's #Override onCreate method is never called.
EDIT 1: Ok, I did found the problem: When I added addPreferencesFromResource(prefs) in the activity's onCreate method as a debug-test, I found out that the MyPreferenceFragment-class is indeed being initialized, then it finishes the activity's onCreate method (which would have failed at findPreference() if I didn't added the addPreferencesFromResource(prefs) test-line), and only after the activity's onCreate method is completely finished, it goes to the MyPreferenceFragment's onCreate method.
Is there a way to let the PreferenceFrament's onCreate method go first, while in the middle of the activity's onCreate method, so after AddResourceApi11AndGreater() but before findPreference(LIST_PREFERENCE)?
Move your logic to PF, don't do things in PreferenceActivity.
There are also changes in the way of listening to the preferences changes. Check the code.
public class MyPrefsActivity extends PreferenceActivity {
private static int prefs = R.xml.settings;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try{
getClass().getMethod("getFragmentManager");
AddResourceApi11AndGreater();
}
catch(NoSuchMethodException e){ // Android API < 11
AddResourceApiLessThan11();
}
}
#SuppressWarnings("deprecation")
protected void AddResourceApiLessThan11(){
addPreferencesFromResource(prefs);
}
#TargetApi(11)
protected void AddResourceApi11AndGreater(){
getFragmentManager().beginTransaction().replace(android.R.id.content,
new PF()).commit();
}
#TargetApi(11)
public static class PF extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener {
private ImageButton cbButton, spinnerButton, popupButton;
private final String LIST_PREFERENCE = "prefCheckboxOption";
#Override
public void onCreate(final Bundle savedInstanceState){
super.onCreate(savedInstanceState);
addPreferencesFromResource(MyPrefsActivity.prefs); // outer class
// private members seem to be visible for inner class, and
// making it static made things so much easier
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
preferences.registerOnSharedPreferenceChangeListener(this);
ListPreference listPreference = (ListPreference) findPreference(LIST_PREFERENCE);
if(listPreference.getValue() == null)
listPreference.setValue("0");
cbButton = (ImageButton) MainActivity.mActivity.findViewById(R.id.ibtnCheckbox);
spinnerButton = (ImageButton) MainActivity.mActivity.findViewById(R.id.ibtnSpinner);
popupButton = (ImageButton) MainActivity.mActivity.findViewById(R.id.ibtnPopup);
setChosenPreference(Integer.valueOf(preferences.getString(LIST_PREFERENCE, "0")));
}
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
int chosen_option = Integer.valueOf(sharedPreferences.getString(key, "0"));
setChosenPreference(chosen_option);
}
private void setChosenPreference(int chosen_value){
// First put all Visibilities on GONE
cbButton.setVisibility(View.GONE);
spinnerButton.setVisibility(View.GONE);
popupButton.setVisibility(View.GONE);
// Then turn the chosen on VISIBLE again
switch(chosen_value){
case 0: // Multi-Click CheckBox
default:
cbButton.setVisibility(View.VISIBLE);
break;
case 1: // Dropdown CheckBox
spinnerButton.setVisibility(View.VISIBLE);
break;
case 2: // Pop-up CheckBox
popupButton.setVisibility(View.VISIBLE);
break;
}
}
}
}
I implemented a bottom button bar(something like a tab bar controller in iPhone). For this I created a common layout (button_bar.xml, 5 image buttons) and included in other activity xml files. and for the managing the click action I created a BaseActivity.java extended from Activity and perform the click actions. and I extend other activity which need button bar from this BaseActivity, which works fine. Now I want to include a selected state to these buttons, but when I access the buttons in base activity it give a null pointer error. How can I solve this.
button_bar.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/bottomButtonBar"
style="#android:style/ButtonBar"
... >
<ImageButton
android:id="#+id/btnGuests"
android:onClick="showAllGuests"
android:src="#drawable/ic_guest_list" />
<ImageButton
android:id="#+id/btnAddGuest"
android:onClick="selectGuestType"
android:src="#drawable/ic_add_guest" />
<ImageButton
android:id="#+id/btnAddParty"
android:onClick="showAddParty"
android:src="#drawable/ic_add_party" />
....
</LinearLayout>
public class BaseActivity extends Activity {
// common to other activities.
public void showAddParty(View view) {
//showAddParty is one one of the buttons click method. 4 more buttons are there
Intent intent = new Intent(this, AddPartyActivity.class);
startActivity(intent);
// I can get "view.findViewById(R.id.btnAddParty)" here
// but I can't get "findViewById(R.id.btnAddGuest)" here. how this possible
}
}
public class AddPartyActivity extends BaseActivity{
....
}
Here i can get the corresponding view from parameter view, and change backgroundIbageSource. but when it goes to "AddPartyActivity" that inherited from Baseactivity, the new image is replaced by old one. How can I implement the selected feature in BaseActivity itself?
you can hold the state of the Button(clicked or not) using booloean in BaseActivity and check the value of these variables in AddPropertyActivity's onCreate() method.
public class BaseActivity extends Activity {
protected static boolean isButton1Clicked = false;
protected static boolean isButton2Clicked = false;
protected static boolean isButton3Clicked = false;
protected static boolean isButton4Clicked = false;
.....
public void showAddParty(View view) {
isButton1Clicked = true;
//showAddParty is one one of the buttons click method. 4 more buttons are there
Intent intent = new Intent(this, AddPartyActivity.class);
startActivity(intent);
}
}
public class AddPartyActivity extends BaseActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_layout);
Button button1 = (Button)findViewById(R.id.button1);
if(isButton1Clicked) {
button1.setBackground(R.drawable.clicked);
} else {
button1.setBackground(R.drawable.not_clicked);
}
......
......
}
}
and remember that all boolean variables must be static variables. (every object will have it's own copy of instance variables but all objects will share a single copy of static members).
public class BaseActivity extends Activity {
protected static boolean isButton1Clicked = false;
protected static boolean isButton2Clicked = false;
protected static boolean isButton3Clicked = false;
protected static boolean isButton4Clicked = false;
protected Button button1;
protected Button button2;
protected Button button3;
protected Button button4;
protected void checkButtonsState() {
if (isButton1Clicked) {
button1.setBackgroundResource(R.drawable.image1);
} else {
button1.setBackgroundResource(R.drawable.image2);
}
..........
}
public void showAddParty(View view) {
isButton1Clicked = true;
// showAddParty is one one of the buttons click method. 4 more
// buttons are there
Intent intent = new Intent(this, AddPartyActivity.class);
startActivity(intent);
}
}
public class AddPartyActivity extends BaseActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button1 = (Button) findViewById(R.id.button);
button2 = (Button) findViewById(R.id.item1);
.....
checkButtonsState();
}
}
Your error come from because you are using view.findViewById(), but the view variable correspond of the object that catch the click event (look in your xml, the 'android:onClick="showAddParty"').
So, you have in parameter a view instance that point directly to the btnAddParty button.
Is why you can access with findViewById to btnAddParty id but not btnAddGuest id.
You can access to all the view hierarchy by using direct findViewById as method of the activity class:
View btAddParty = findViewById(R.id.btnAddParty)
View btAddGuest = view.findViewById(R.id.btnAddGuest)
Now, you can have a full solution, by implement a special method (setMyInternalContent in the sample below) in the BaseActivity and keep an instance of each button, after, you just have to update there state on click action:
public class BaseActivity extends Activity {
protected Button mBtAddParty;
protected Button mBtAddGuest;
// ...
protected void setMyContentView(int resId) {
setContentView(resId);
mBtAddParty = (Button)findViewById(R.id.btnAddParty);
mBtAddParty = (Button)findViewById(R.id.btnAddGuest);
// ...
}
public void showAddParty(View view) {
mBtAddParty.setClickable(true);
mBtAddGuest.setClickable(false);
// ...
//showAddParty is one one of the buttons click method. 4 more buttons are there
Intent intent = new Intent(this, AddPartyActivity.class);
startActivity(intent);
}
}
public class AddPartyActivity extends BaseActivity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setMyContentView(R.layout.activity_layout);
// Do not forget to set initial button state:
mBtAddParty.setClickable(true);
mBtAddGuest.setClickable(false);
// ...
}
}
OK so here is some code. Seems to have no errors however when run in Android Studio I am getting "Unfortunately, NameOfApplication has stopped". I have no idea what is wrong with it.
public class MainActivity extends Activity implements OnClickListener {
EditText centimeters = (EditText) findViewById(R.id.editCentimeters);
EditText inches = (EditText) findViewById(R.id.editInches);
Button btnConverter = (Button) findViewById(R.id.button);
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnConverter.setOnClickListener(this);
}
#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;
}
#Override
public void onClick(View view) {
switch(view.getId()){
case R.id.button:
double c = Double.valueOf(centimeters.getText().toString());
double i = c * 0.393701;
inches.setText(String.valueOf(i));
break;
default:
break;
}
}
}
I have another question as well. It is my beginning with Android and the reference api is quite big so what would you recommend as a best and quickest way to learn it? Get a basic understanding of its structure etc.?
You have to initialise UI elements after calling setContentView() in the onCreate() method like this:
EditText centimeters;
EditText inches;
Button btnConverter;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
centimeters = (EditText) findViewById(R.id.editCentimeters);
inches = (EditText) findViewById(R.id.editInches);
btnConverter = (Button) findViewById(R.id.button);
btnConverter.setOnClickListener(this);
}
public class MainActivity extends Activity implements OnClickListener {
//You need the global variables to access the data from onClick, altough you could findViewById inside the onClick itself not to have global variables that exist during the whole activity life.
private EditText centimeters;
private EditText inches;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Here you set the view (setContentView(R.layout.activity_main)) so after this line is when you can start looking for your views declared in the xml layout file, "activity_main.xml
setContentView(R.layout.activity_main);
//We can look for the views form here
centimeters = (EditText) findViewById(R.id.editCentimeters);
inches = (EditText) findViewById(R.id.editInches);
Button btnConverter = (Button) findViewById(R.id.button);
btnConverter.setOnClickListener(this);
}
....
The rest the same
I want write code once and use in different activities. I have created a Base Activity class for that . Also the header of all the layouts in different activities are same. I have done that with the help of the <include layout > tag.
Now the Problem is my BaseActivity code is not running. I am trying this first time se don't have much idea about that.
1.)The BaseActivity code is below :
package com.waheguru.app;
import android.R.integer;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
public abstract class BaseActivityMenu extends Activity {
//action id
private static final int ID_UP = 1;
private static final int ID_DOWN = 2;
private static final int ID_SEARCH = 3;
private static final int ID_INFO = 4;
private static final int ID_ERASE = 5;
private static final int ID_OK = 6;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.header);
ActionItem nextItem = new ActionItem(ID_DOWN, "Book", getResources().getDrawable(R.drawable.menu_down_arrow));
ActionItem prevItem = new ActionItem(ID_UP, "Bookmark", getResources().getDrawable(R.drawable.menu_up_arrow));
ActionItem searchItem = new ActionItem(ID_SEARCH, "Find", getResources().getDrawable(R.drawable.menu_search));
ActionItem infoItem = new ActionItem(ID_INFO, "Info", getResources().getDrawable(R.drawable.menu_info));
ActionItem eraseItem = new ActionItem(ID_ERASE, "Clear", getResources().getDrawable(R.drawable.menu_eraser));
ActionItem okItem = new ActionItem(ID_OK, "OK", getResources().getDrawable(R.drawable.menu_ok));
//use setSticky(true) to disable QuickAction dialog being dismissed after an item is clicked
prevItem.setSticky(true);
nextItem.setSticky(true);
//create QuickAction. Use QuickAction.VERTICAL or QuickAction.HORIZONTAL param to define layout
//orientation
final QuickAction quickAction = new QuickAction(this, QuickAction.VERTICAL);
//add action items into QuickAction
quickAction.addActionItem(nextItem);
quickAction.addActionItem(prevItem);
quickAction.addActionItem(searchItem);
quickAction.addActionItem(infoItem);
quickAction.addActionItem(eraseItem);
quickAction.addActionItem(okItem);
//Set listener for action item clicked
quickAction.setOnActionItemClickListener(new QuickAction.OnActionItemClickListener() {
public void onItemClick(QuickAction source, int pos, int actionId) {
ActionItem actionItem = quickAction.getActionItem(pos);
//here we can filter which action item was clicked with pos or actionId parameter
if (actionId == ID_SEARCH) {
Toast.makeText(getApplicationContext(), "Let's do some search action", Toast.LENGTH_SHORT).show();
} else if (actionId == ID_INFO) {
Toast.makeText(getApplicationContext(), "I have no info this time", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getApplicationContext(), actionItem.getTitle() + " selected", Toast.LENGTH_SHORT).show();
}
}
});
//set listnener for on dismiss event, this listener will be called only if QuickAction dialog was dismissed
//by clicking the area outside the dialog.
quickAction.setOnDismissListener(new QuickAction.OnDismissListener() {
public void onDismiss() {
Toast.makeText(getApplicationContext(), "Dismissed", Toast.LENGTH_SHORT).show();
}
});
Button books=(Button)findViewById(R.id.book);
books.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Intent intent=new Intent(ExampleActivity.this,List_of_books.class);
startActivityForResult(intent, 0);
}
});
//show on btn1
Button btn1 = (Button) this.findViewById(R.id.menu);
btn1.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
quickAction.show(v);
}
});
}
}
2.) The Activity extended the Base Activity
package com.waheguru.app;
import android.app.Activity;
import android.os.Bundle;
public class ABCActivity extends BaseActivityMenu {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.home);
}
}
So can any one help me where I am doing something wrong.
For this you have to create one header.xml which will be included in each and every layout for your activities as follows
header.xml
<RelativeLayout>
<TextView android:id="#+id/txtHeading"
.... />
</RelativeLayout>
activity_main.xml
<RelativeLayout>
<!-- include your header here -->
<include layout="#layout/header"
... />
<!-- Rest of your views -->
</RelativeLayout>
BaseActivity
abstract class BaseActivity extends Activity {
protected TextView txtHeading;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
protected void setHeading(int resId) {
if(txtHeading == null)
txtHeading = findViewById(R.id.txtHeading);
if(txtHeading != null)
txtHeading.setText(resId);
}
}
MainActivity
class MainActivity extends BaseActivity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setHeading(R.string.heading_main);
}
}
You can put as many views you want and manage common things in BaseActivity or BaseListActivity.
If you are making inheritance with activities and your base activity calls setContentView and after that the real activity calls setContentView the last call will set the layout for activity. So if you are looking for a solution where all activies have the same header component the are 2 ways.
For each activity layout xml you include that component
-You make function for baseActivity e.g. setContent(int layout_id)
-You call that with your activity always.
-Baseactivity inflates a root view with header and inflates layout_id view to that layout.
-Then calls the actual setContentView with that component.
I think you should achieve it using Fragment, this may helps you.
1 - in main.xml, add:
<fragment
android:id="#+id/header"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
class="com.package.name.HeaderPanel" />
//remaining is same
2 - the BaseActivity which extends FragmentActivity:
public class BaseActivityMenu extends FragmentActivity {
private static final String TAG = Default.class.getName() + " - ";
private int mResLayoutId;
public void onCreate(Bundle savedInstanceState, int resLayout){
super.onCreate(savedInstanceState);
setContentView(resLayout);
mResLayoutId = resLayout;
switch(mResLayoutId){
// here change with your xml file
case R.layout.home:
// set here common control like header textview
break;
default:
break;
}
}
}
3 - Now, you can extend your Activity with the BaseActivity. This will allow the Activity to be extended by FragmentActivity:
public class ABCActivity extends BaseActivityMenu {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState, R.layout.home);
}
}
In code, your base activity is called ExampleActivity, but in your child class you are extending BaseActivityMenu. Don't know where its coming from.
Perhaps change:
public class ABCActivity extends BaseActivityMenu
To this:
public class ABCActivity extends ExampleActivity
Moreover, I would suggest you to define your base activity (ExampleActivity) as an Abstract class.
For example:
public abstract class ExampleActivity extends Activity
Doing so will not define your base class as concrete and will make it easier to debug in case of problems.