In various activities I have very similar methods.
For example:
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.ibHome:
Intent menuIntent = new Intent(v.getContext(),Menu.class);
startActivity(menuIntent);
break;
}
}
and
#Override
public void onClick(View v) {
/** */
//
switch(v.getId()){
case R.id.bNew:
Intent newSwimmerIntent = new Intent(v.getContext(),NewSwimmer.class);
startActivity(newSwimmerIntent);
break;
case R.id.ibHome:
Intent menuIntent = new Intent(v.getContext(),Menu.class);
startActivity(menuIntent);
break;
is there a way (which I assume would be using inheritance) to prevent the menuIntent being explicitly stated in each each class?
Thanks.
You could use inheritance, but that actually may not be the best choice, especially if the two activities are not directly related in an "Is-A" relationship.
In this case, you're probably better off declaring a new class that implements OnClickListener interface. You can then instantiate that class and bind it to your buttons' click events wherever they're used.
Here's an example:
public class HomeButtonHandler implements OnClickListener{
#Override
public void onClick(View v) {
Intent menuIntent = new Intent(v.getContext(),Menu.class);
v.getContext().startActivity(menuIntent);
}
}
And in your activities, you can just bind the HomeButtonHandler to the onClickListner of the button:
homeButton.setOnClickListener(new HomeButtonHandler());
Create a common BaseActivity for all your activities, then override only the BaseActivity.onClick() method.
In this way you will have a single switch for all your activities.
Related
How to access data of the Starting activity into Started activity.
like i have given the following snippet for better understanding.
BaseActivity.java
class BaseActivity extends AppCompatActivity{
...
btnCust = (Button) findViewById(R.id.btnCust);
btnCust.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
String flag ="CU";
Intent i = new Intent(getBaseContext(),ChildActivity.class);
i.putExtra("flag", flag);
startActivity(i);
}
});
public int add(int a,int b){
return a+b;
}
...
}
Now how to access BaseActivity Add() Method into ChildActivity.
ChildActivity.java
class ChildActivity extends AppCompatActivity{
...
btnCust = (Button) findViewById(R.id.btnCust);
btnCust.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
String flag ="CU";
BaseActivity a = getBaseActivity();///here i want read the object of base activity
int add = a.add(20,50);
}
});
...
}
Can anyone know that how to solve this problem which is i`m trying too much time.
Please help me.
Thanks in advance.
I have tried with Serializable and Parcelable, but still not working.
You can easily use ViewModel and move your logic into it and use them into shareable in any activity, fragment or composable screens.
I need to define a layout for multiple activities in android and from the UI part, it is successful. But to code those elements to perform on each click listeners, I need to define it in all the java pages I use.
Can we globally define this in a java page and include it in the required pages?
menuButton = findViewById(R.id.menuButton);
menuButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent i = new Intent(getApplicationContext(), MenuActivity.class);
startActivity(i);
finish();
overridePendingTransition(0, 0);
}
});
Yes and No.
You can create a BaseActivity which has the common logic that has to be executed for each button click.
But you need to implement the listener for the button on specific activity, since life cycle of each activity is independent of other activity.
To make the code readable better (avoiding implementing listener/setOnclickListener), you can use ButterKinfe, and create a method for OnClick() annotation, and call the method in BaseActivity.
What you essentially want to do is call the findViewById(), which can only be called if you have a reference to a Context variable. You should use your Activity Context, hence you pass this to the static function, which can then access all methods accessible via Context .
public class ExampleActivity2 extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MenuUtils.setListener(this);
}
}
Define the static class like this:
public static class MenuUtils{
public static void setListener(Context context){
menuButton = context.findViewById(R.id.menuButton);
menuButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// do stuff
}
});
}
}
What you should be careful about is that any Activity you pass to this function should have a menuButton in it's layout, otherwise you run the risk of getting a NullPointerException, which is when findViewById() cannot find menuButton.
I am working on an android app that has a menu at the top (like we have in websites; home, aboutus etc). This menu is repeated in all the activities so I have to repeat the code for these in all activities. Is there a way that I can write the code once in some class and reuse it in all other activities using inheritance or something? (Just lice there is include function in php). Hope my question is straight forward. Here is the code for the menu that I have to repeat everywhere.
// menu items
menu_home.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent i = new Intent(CurrentActivity.this, HomeActivity.class);
startActivity(i);
}
});
menu_help.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent i = new Intent(CurrentActivity.this, HelpActivity.class);
startActivity(i);
}
});
menu_media.setOnClickListener(new OnClickListener() {;
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent i = new Intent(CurrentActivity.this, MediaActivity.class);
startActivity(i);
}
});
menu_index.setOnClickListener(new OnClickListener() {;
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent i = new Intent(HomeActivity.this, IndexActivity.class);
startActivity(i);
}
});
I have to repeat the code for these in all activities.
Java does not support multiple inheritances.
Don’t use inheritance just to get code reuse. If there is no is a relationship then use composition for code reuse. Overuse of implementation inheritance (aka extends) can break all the sub-classes, if the superclass is modified.
In you case I would use composition. Just create new class that implements above mentioned Listener logic.
Yes you can..for this take one MainActivty and write your menu code in that..after then all your activitys extend that MainActivity like below..
class MainActivty extend Activity{
}
class FirstActivity extend MainActivity{
}
class SecondActivity extend MainActivity{
}
Then menu will appear in your all activitys..
Yes you can create a layout and include it like this:
<include
android:id="#+id/headerLayout"
layout="#layout/login_header"
/>
It has its own class file where common functionality can be kept.
it's very easy you just create a class
class MenuActivty extend Activity{
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
((Button)findViewById(R.id.mymenu_home).setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent i = new Intent(this, HomeActivity.class);
startActivity(i);
}
});
((Button)findViewById(R.id.mymenu_help).setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent i = new Intent(this, HelpActivity.class);
startActivity(i);
}
});
//... same thing for the others
}
}
be careful to rename the menu "mymenu" in all the XML
and all the classes where you want to use the menu should be extended MenuActivty
and in the XML use
<include layout="#layout/menulayout "
android:id="#+id/mymenu"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
and create an XML file named menulayout where you put the layout of your menu.
Follow these steps:
Create a generic layout for menu and include it wherever you want to use it.
<include
android:id="#+id/headerLayout"
layout="#layout/login_header"
/>
Create a class CentralizedHeader. Create on constructor with one parameter of activity type.
Create a function here and initialize all views and perform all related functionality here.
public class CentralizedHeader {
private Button btnHome, btnContribute;
private Activity activity;
public CentralizedHeader(Activity activity) {
this.activity = activity;
}
public void headerActions() {
btnHome = (Button) activity.findViewById(R.id.btn_home);
btnContribute = (Button) activity.findViewById(R.id.btn_contribute);
btnHome.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(activity, MorePackagesActivity.class);
activity.startActivity(intent);
}
});
btnContribute.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(activity, ContributeActivity.class);
activity.startActivity(intent);
}
});
}
}
Create an object of this class in other activity and call its function. ie
public class MainActivity extends Activity {
private CentralizedHeader headerCentralized;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.fragment_home_tab);
headerCentralized = new CentralizedHeader(this);
headerCentralized.headerActions();
}
}
Use only one Activity that have all the menus and create Fragments for activity. Replace fragment on clicking to the menu. This is the good way to achieve your functionality as you want.
Steps to reuse function in java class:
make a Singleton class so that that instance is anywhere you can get
mention all your code in this class
use all method from this class
and if you use that layout also then just make one xml and include it in all layout where you want to add.
I have a good background in C, and now I am writing code for android/java.
What I fail to understand that why function definition of a handler function is done inside another function. Code becomes so messy and hard to maintain and understand( from a C programmer POV).
So I have this code
final Button btnOpenPopup = (Button)findViewById(R.id.menuButton);
btnOpenPopup.setOnClickListener(new
Button.OnClickListener()
{...}
Is it possible to have a function
myButtonClickListner() {} defined in the class and btnOpenPopup.setOnClickListener((SomeCast)myButtonClickListner
I think there has to be a way, But I am not able to find it..
Please comment.
Well, there are two ways to do this:
1- Have the containing class implement the OnClickListener interface. For example:
public class MainActivity extends Activity implements OnClickListener{
//...
public void onCreate(Bundle savedState){
//...
final Button btnOpenPopup = (Button)findViewById(R.id.menuButton);
btnOpenPopup.setOnClickListener(this);
}
public void onClick(View v){
switch(v.getId()){
case R.id.button1:
//
break;
}
}
2- The second method is the one described by Selvin in his comment: creating a separate class, which implements the OnClickListener interface, and instantiate it in your onCreate(). So, assuming that you have a myButtonListener class in its own myButtonListener.java file, you can simply do:
final Button btnOpenPopup = (Button)findViewById(R.id.menuButton);
btnOpenPopup.setOnClickListener(new myButtonListener);
The idea behind using
final Button btnOpenPopup = (Button)findViewById(R.id.menuButton);
btnOpenPopup.setOnClickListener(new
Button.OnClickListener()
{...}
such coding style is that the object and its implementation stays together at one place.
in above code we have used anonymous innerclass.
If you are not comfortable with such implementation then there is also another way of doing this.
In your activity, implement onClickListener like below:
public class MainActivity extends Activity implements OnClickListener{
Button btnOk;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//find id of your button
btnOk = (Button) findViewById(R.id.btnOk);
//Registering it for click listener
btnOk.setOnClickListener(this);
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btnOk:
System.out.println("OK button is clicked");
break;
case 2:
//some other controls
break;
default:
break;
}
}
}
Implement View.OnClickListener on your class and override its onClick method. That would make the code somewhat cleaner.
But first i recommend you to have proper knowledge of OOP and Java.
You just need to implement the OnClickListener interface and override the onCLick method. And on your onCLick() method you just need to add a filter for the corresponding View.
public void onClick(View arg0){
if(arg0 == myButton){
//do stuff when myButton is click
}else if(arg0 == myOtherButton){
//do stuff when myOtherButton is click
}
}
- What you have encountered is know as Anonymous Inner Class.
Anonymous Inner Class:
It has no name.
It must implements or extends one and only one Interface or Class respectively.
- This is just a way of coding where you keeping the functionality of that view or component attached visually.
The another way you can do that is by doing the following:
- Implement the specific Interface that has the call-back method.
public class MainActivity implements OnItemClickListener{
private Button buttonClick;
....
....
onCreate(Bundle saveInstance){
super.onCreate(savedInstanceState);
setContentView(R.layout.main_view);
buttonClick = (Button)findViewById(R.id.button_click);
buttonClick.setOnClickListener(this);
...
...
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button_click:
// -------- Do you function here
break;
}
}
}
Well lets say that I have an app that have like 50-60 buttons all around and I want to handle all click methods inside other package. How could I handle click for package app.test; class one in package app.test.clicks class clicks?
Create a class which implements OnClickListener,
public class ClickHandler implements OnClickListener
{
public void onClick(View v) {
//This method will be automatically implemented once OnClickListener is implemented.
}
}
Now set the onClickistener to your button like this,.
button.setOnClickListener(new ClickHandler());
And now inside the onClick() just do this,
public void onClick(View v) {
if(v.getId()==R.id.button)
{
//your stuff here.
}
}
If you need context object then,try v.getContext();. "v" is the parameter form the onClick().
make sure you import the package name of your ClickHandler class into your Activity.
But it would be much better if you had this as an inner class for each Activity.
public class HeaderActivity extends Activity implements OnClickListener{
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
((Button)findViewById(R.id.home)).setOnClickListener(this);
((Button)findViewById(R.id.search)).setOnClickListener(this);
((Button)findViewById(R.id.list)).setOnClickListener(this);
((Button)findViewById(R.id.filter)).setOnClickListener(this);
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch(v.getId()){
case R.id.home:
Intent home=new Intent(this,HomeScreen.class);
startActivity(home);
finish();
break;
case R.id.search:
Intent search=new Intent(this,SearchScreen.class);
startActivity(search);
finish();
break;
case R.id.list:
Intent list=new Intent(this,ListScreen.class);
startActivity(list);
finish();
break;
case R.id.filter:
Intent filter=new Intent(this,FilterScreen.class);
startActivity(filter);
finish();
break;
default : break;
}
}
Well I don't think it will be a great idea to implement. However you need to pass the Context to clicks class. From context object you'll be able to get to the control which has been clicked and you can write your logic accordingly.