How to initialize interface in Activity. - java

I need to call a method in fragment when a certain item is selected in navigation drawer activity.
For this, I've created one interface which I Will be initializing & calling a method from the activity, Also I'll implement this interface in Fragment and override this method.
Here is code snippet for declaring an interface.
public interface AlertForDiscardDefaultProfileChanges {
void alertForDiscardDefaultProfileChanges(int navigationItemID);
}
And this is how I'm initializing in activity.
private AlertForDiscardDefaultProfileChanges alertForDiscardDefaultProfileChanges;
#Override
public void onCreate(Bundle savedInstanceState) {
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dashboard);
alertForDiscardDefaultProfileChanges = (AlertForDiscardDefaultProfileChanges) this;
}
Here I'm getting java.lang.ClassCastException for initializing it.
Not sure what I'm missing here or what's wrong.

you have to implements this interface to your activity/fragment for eg :
MainActivity :
public class MainActivity extends AppCompatActivity implements FragmentClassName.AlertForDiscardDefaultProfileChanges{
//override methods
#Override
public void alertForDiscardDefaultProfileChanges(String navigationItemID) {
// now use navigationItemID here...
}
}

Here is how I achieved it,
I called a method through an object of a fragment in which I wanted to implement a method.
Fragment Class -
public class DefaultProfileFragment extends Fragment implements
AlertForDiscardDefaultProfileChanges {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_default_profile, container,
false);
mContext = view.getContext();
return view;
}
#Override
public void alertForDiscardDefaultProfileChanges(int navigationItemID) {
showDismissWarning(navigationItemID);
}
Activity from which I need to call interface method.
A Just simple object of a fragment class and name of a method. Nothing fancy needs to be done. No need to initialize an interface.
(new DefaultProfileFragment()).alertForDiscardDefaultProfileChang‌​‌​es(id);

Step-1
public interface AlertForDiscardDefaultProfileChanges {
void alertForDiscardDefaultProfileChanges(int navigationItemID);
}
define this method from which activity and class you want transfer your data
Step 2 -
Define this method also in step 1 class.
private AlertForDiscardDefaultProfileChanges favListner;
public void setAlertOnDiscardListner(AlertForDiscardDefaultProfileChanges
favOnTouchListner) {
favListner = favOnTouchListner;
}
Step -3 .
pass value from Step 1 class like below
favListner.alertForDiscardDefaultProfileChanges(int navigationItemID);
Step-4
In which class you want data first implement that interface like.
Class A implements YourActivity_where_interface define.AlertForDiscardDefaultProfileChanges{
override Method.
}
Step 5.
You Should have to do one thing also in that class where you want data .
You should have to initialise interface from on Create method like below.
YourActivity_where_interface define.setAlertOnDiscardListner(this);
Done now you can play with it.

Related

How to inject an object passed to the BaseActivity, instantiating it with reflection (or any other way if possible)

I have a BaseActivity, in which I am trying to retrieve the instance of a subclass in order to inject it with dagger.
I've been trying to figure out a way to not check manually the object passed on is an instance of every single Activity, but if there is a more optimal way of doing it.
F.i., if the component is as such:
AppComponent
#Singleton
#Component(modules = {AppModule.class})
public class AppComponent {
public void inject(FooActivity fooActivity);
public void inject(BarActivity barActivity);
public void inject(…);
}
Each activity extends BaseActivity and we have something like:
FooActivity
public class FooActivity extends BaseActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.inject(this);
}
}
Last, the issue comes when handling the BaseActivity.
BaseActivity
current implementation
...
public void inject(FooActivity fooActivity) {
DaggerAppComponent.create().inject(fooActivity)
}
public void inject(BarActivity barActivity) {
DaggerAppComponent.create().inject(barActivity)
}
...
However, I am looking for a more optimal way that reduces boilerplate, so I have been thinking something like the following:
BaseActivity
...
public void inject(Object activity) {
// retrieve the instance of the activity
// if possible and handle it so then we can:
DaggerAppComponent.create().inject(activity)
}
...
But since I am required to find its instance, instead of having a series of if statements with instanceof, which I will need to update for every new activity, is there a way to handle it in a more automated way?

Can't understand use of this keyword in View.setOnClickListner(this)?

I know that keyword this refers to current instance of class. But When we implement View.OnClickListener in our class then on calling method textview.setOnClickListener(this), How does argument this(instance object of class) of setOnClickListener(this) call automatically onClick() method. Is there any code in view class which take object and call onClick method on this code or something else is going on?
I want to know what is going behind the scenes, how does android reaches from this keyword to onClick() method? That is what I want to ask?
OnClickListener is an interface in class View.
If your activity implements this interface by setting:
public class MainActivity extends AppCompatActivity implements View.OnClickListener
then you can set a listener for a view like button:
myButton.setOnClickListener(this);
and override the onClick method implementing it like this:
#Override
public void onClick(View v) {
// your code here
}
so a simple explanation is: this means that your view will use your activity's overridden onClick method.
To implement the View.setOnclickListener in your code you need to first implement the public static interface View.OnClickListener.
like this
public class MyActivity extends Activity implements View.OnClickListener {
}
The above interface contains public void abstract method "onClick(View v)" which you override to put your logics
This method is called when a view has been clicked.
for sake of simplicity i have created the code
// Create an anonymous implementation of OnClickListener
private OnClickListener mCorkyListener = new OnClickListener() {
public void onClick(View v) {
// do something when the button is clicked
}
};
protected void onCreate(Bundle savedValues) {
...
// Capture our button from layout
Button button = (Button)findViewById(R.id.corky);
// Register the onClick listener with the implementation above
button.setOnClickListener(mCorkyListener);
...
}
here OnclickListener is an interface which have object mCorkyListener
similarly you can use this keyword instead mCorkyListener
‘this’ represents the instance of the current class. You can access the properties and functions of the current class with ‘this’ keyword.
Let's have an interface ElectricityBill
public interface ElectricityBill{
public void pay(int amount);
}
now there are two ways you can pay an electricity bill either by going to nearby electricity board office
ElectricityBill bill = new ElectricityBill(){
#Override
public void pay(int amount){
}
}
payBill(bill);
or by paying the bill online
public class User implements ElectricityBill{
.....
#Override
public void pay(int amount){
}
}
.....
payBill(this);
}
in both the cases, the user has to pay XXX amount, similar is the case if you want to listen to input events you either have to pass the original View.OnClickListener object or implement it and pass this to make it work.
Edit:
when you pass this you tell the current class to handle the click events itself and has to override the onClick() to do so. And when you pass object you let the original class to handle the onClick by creating an anonymouse class and implementing onClick(). but when you pass this your current class get's the authority to listen to input events. It becomes on the type of OnClicklistener and gets the authority to listen onClick()

move bundle without using intents - android

Is there any way in which I can move a bundle of data from one class to another without actually changing the layout?
For example:
I have 3 classes: class A, B and C.
Now class B has navigation drawer and bottom navigation menu implemented which can be seen on class A and C and also be used at the same time.
However, I have a button in the bottom navigation menu which takes me to class C but the data which I need to view in this is in class A.
Is there any way by which I can just send a bundle of data to class B but without using intents, then retrieve the data from class B and show it on class C?
** EDIT **
P.S : B is an AppCombatActivity extended class and A and C are Fragment extended classes.
Your question is very simple to implement but it can also become a headache. This is what you should do.
class A:
public class A extends Activity {
static A INSTANCE;
String data="A";
#Override
public void onCreate(Bundle savedInstanceState) {
INSTANCE=this;
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
public static A getActivityInstance()
{
return INSTANCE;
}
public String getData()
{
return this.data;
}
}
class B:
public class B extends Activity {
String data;
#Override
public void onCreate(Bundle savedInstanceState) {
data=A.getActivityInstance().getData();
}
}
The trick is to create an Instance in class A and then using that instance to access all the public elements like methods, variables etc using that Instance.
Hope this helps :)
I would suggest using a SharedPreferences file to store the data in Class A. Then you can read from the SharedPreferences file wherever you want to show the data.
Refer this page -
https://developer.android.com/training/basics/data-storage/shared-preferences.html
You could use interface for passing data, this the reference
https://stackoverflow.com/a/9977370/2951976

Call a method in MainActivity.java on event that happens in a library file

I included the library Swipeable-Cards in my android project. In MainActvitiy.java the onCreate method includes something like that:
SimpleCardStackAdapter adapter = new SimpleCardStackAdapter(this);
//This should also be done on an event in the library class:
adapter.add(new CardModel("Title2", "Description2 goes here", r.getDrawable(R.drawable.picture2)));
Now, in the CardContainer.java (which belongs to the swipeable cards library) there is an event on which I want a new item added to the adapteradapter.add(...). The adapter was defined in the MainActvitiy.java as you can see above.
How can I achieve this?
I first thought about defining a new method in MainActivity and then calling it from my library-class, like that:
public void callfromlibrary() {
adapter.add(...);
}
However then the method and the adapter need to be defined static, additionally I don't know how to make this method of MainActivity available in CardContainer.java.
I believe I need to create kind of a listener to check in the MainActivity what happens in CardContainer.java? I don't know how to do this.
Any help is appreciated!
To allow CardContainer to communicate up to the MainActivity, you define an interface in CardContainer and implement it in MainActivity. When the event occurs in CardContainer, it can then call Interface method in order to add the CardModel to the adapater.
public class CardContainer extends ... {
CardContainerEventListener mCallback;
// Define a interface
public interface CardContainerEventListener {
public void addToAdapter();
}
// Method to register callback
void registerCallback(Activity callback) {
mCallback = (CardContainerEventListener) callback;
}
void someFunction() {
// Event got generated, invoke callback method
mCallback.addToAdapter();
}
}
public class MainActivity extends Activity implements CardContainer.CardContainerEventListener {
// Ensure you register MainActivity with CardContainer, by calling
// cardContainer.registerCallback(this)
public void addToAdapter() {
adapter.add(...);
}
}
please use a Java Interface for achieving this..
declare an interface in the cardcontainer class
public interface yourInterface{
public void callfromlibrary();
}
and intialize the object for calling the function
yourInterface object = (yourInterface) MainActivity;
and implement the interface in your main activity like
Class MainActivity extends activity implements yourInterface
and implement callfromlibrary() method
call this method from cardcontainer class whenever you needed using the object you have created ..
object.callfromlibrary()

Adapter.getItem(position) crashes application

I'm writing an Android Application with a custom Adapter for a list view.
The adapter is a variable in the mainActivity class and contains a list of custom classes. I need to access a class in this list from an other activity, but the application seems to crash when it reaches getItem(position) in the adapter.
Basically this is what the application looks like:
in the MainActivity class there is a basic custom adapter:
public class MainActivity extends Activity {
public static MyAdapter myAdapter;
...
}
The adapter only has the basic functions like getItem and has a list of custom (basic) classes
public class MyAdapter extends BaseAdapter {
private ArrayList<MyClass> tours = new ArrayList<MyClass>();
#Override
public Object getItem(int arg0) {
return getItem(arg0);
}
...
}
When the other activity is opened, an index is passed to it to access a certain Object from the list.
The only problem is that when I try to access a class from this list, the application crashes...
I used following code to access the class from the list in the adapter:
MyClass myClass = (MyClass)MainActivity.myAdapter.getItem(index);
Can someone tell me what I'm doing wrong or why the app crashes?
This is recursive logic:
#Override
public Object getItem(int arg0) {
return getItem(arg0);
}
There's no way for this method to complete, it simply calls itself again and again until the app throws some type of overflow exception. It should be:
#Override
public MyClass getItem(int arg0) {
return tours.get(arg0);
}
Notice how this method returns data from your List.

Categories