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.
Related
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()).alertForDiscardDefaultProfileChanges(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.
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
I have a fragment lets call it EventFragment, and I have an RecyclerView.Adapter called EventAdapter, inside that adapter is a viewholder class called EventViewHolder. I want access an animation method inside the viewholder class from the Fragment.
How would I accomplish this? I was thinking to define another interface to accomplish this.
This is what I have so far:
OnAnimationListener
public interface OnAnimationListener {
void onAnimation();
}
Adapter
public EventAdapter extends RecyclerView.Adapter<RecycleView.ViewHolder> {
// Boilerplate initialization stuff here
public class EventViewHolder extends RecyclerView.ViewHolder implements OnAnimationListener {
// Initialization code
#Override
public void onAnimation() {
// Do an animation
}
}
}
EventFragment
public class EventFragment extends Fragment {
// Boilerplate initialization code
}
I am thinking I should implement an interface inside the Fragment like so:
public class EventFragment extends Fragment implements onAnimationListener {
private void initAdapter() {
mAdapter.setOnAnimationListener(this);
}
#Override
public void onAnimation(Data data) {
// pass any data
}
}
Then I'm sort of stuck at this point. Normally you would call this once the listener is passed through:
OnAnimationListener.onAnimation(...)
But this doesn't make sense. The code flow goes like this:
EventFragment --> Adapter --> ViewHolder
I need to implement the following code flow:
EventFragment (get access to specific viewholder and do animation) <--> Viewholder
How should I accomplish this? Maybe pass the interface from the Viewholder to the Fragment instead, and call mOnAnimationListener.onAnimation() from the fragment right?
I want to have specific control of when the animation occurs on the EventViewHolder and I want to have this control from the EventFragment how should I go about tackling this?
If you simply want to animate the RecyclerView's items you can take a look at RecyclerView.ItemAnimator.
If not (or if you still want to handle this in the fragment) you can attach click listeners for your views inside the ViewHolder object and handle the clicks by passing the event up ViewHolder->Adapter->Fragment via the mechanism you already have (and passing the view received in onClick as a parameter). Personally I'd stay away from this pattern. One reason being that the RecyclerView can be scrolled in the meantime and I don't have enough knowledge right now on what happens to that particular view once it's off position or maybe even off screen. Or maybe pointing to other data.
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()
I have my main class that extends Activity and it's over 2k line so I'm trying to write the code in a different class but not sure what it should extend. I've declared a Context and sent it the context from my main class but when I try something like context.findViewById() it won't let me.
What is the best practice here?
public class HomeScreen extends Activity implements OnItemSelectedListener{
//somewhere in a method, in an onClickListener
new Profile(getApplicationContext()).userCreate();
}
public class Profile{
Context ctx;
int userID;
public Profile (Context ctx)
{
this.ctx=ctx;
}
public void userCreate(){
Button create = (Button) ctx.findViewById()// can't call find view
}
}