I have two views In a single activity StackView and Gridview and 2 corresponding adapters .when I clicked on StackView item it should flip the grid item in Gridview and vice versa?
// activity classs
public class SampleActivity extends Activity implements
OnGridChangeListener {
public void onCreate(bundle){
// replace this with your adapter class.
Adapter adapter = new adapter(this);
}
#override
public void OnGridChange(){
//here you go.
// write code to do what you want.
}
// interface to communicate with activity
public interface OnGridChangeListener {
public void OnGridChange()
}
// adaptor class
public class Adaptor extends "you apapter class to extend"{
OnGridChangeListener onGridChangeListener ;
public Adapter(OnGridChangeListener listener){
onGridChangeListener =listener
}
public getView(){
public void onclick(){
onGridChangeListener.OnGridChange("pass you data");
}
}
}
As per your question this is what i get -
You have a Activity with two independent views which has their own adapters. So when there is changes in one of the adapter you want it to be reflected into another adapter.
The simple solution for your query would be -
When there is a change in first adapter you reflect the change to the activity. after that call the function in the second adapter to reflect the change you want in second adapter.
For this you have to define an interface in first adapter and implement this is activity.
When the first adapter changes call the interface method and this will reflect in activity.
Then call method in second adapter to do the changes you want.
Code example -
MainActivity.Java
public class MainActivity extends AppCompatActivity implements FirstAdapter.callBackMethods {
FirstAdapter firstAdapter;
SecondAdapter secondAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
firstAdapter = new FirstAdapter(MainAtivity.this.getApplicationContext());
//do all the declaration and operation of first adapter. Pass context along with your required params.
secondAdapter = new SecondAdapter();
//do all the declaration and operation of second adapter.
}
//callback method of first adapter
#override
public void callback(){
//changes have been done in FirstAdapter and this methos is fired.
//now do do the changes in SecondAdapter as per req.
if(secondAdapter != null){
secondAdapter.reflectChanges();
}
}
}
FirstAdapter.class
I am taking example of recylerview adapter.
public class FirstAdapter extends RecyclerView.Adapter<FirstAdapter.ViewHolder>{
public FirstAdapter(Context context){
this.context=context;
}
/*
all the boilerplate codes and business logic
*/
//when you want to reflect the changes
callBackMethods callBackMethods = (callBackMethods) context;
callBackMethods.callback();
//this will fireup the implementation in the MainActivity.
public interface callBackMethods{
public void callback();
}
}
SecondAdapter.class
This is where the changes will be reflected.
public class SecondAdapter extends RecyclerView.Adapter<SecondAdapter.ViewHolder>{
/*
all the boilerplate codes and business logic
*/
public void reflectChanges(){
/*
This method will be called from the MainActivity. pass whatever params you want to pass from Activity and do the changes you want to do in the SecondAdapter.
*/
}
}
I hope this solves your problem. Happy coding...
Related
I need show a dialogfragment to press a button on a item from the adapter, and now i make this:
Adapter.class
public class AdaptadorEncuesta extends RecyclerView.Adapter<AdaptadorEncuesta.ViewHolder> {
public class ViewHolder extends RecyclerView.ViewHolder implements
View.OnClickListener {
DialogoGrafica dialogoGrafica = DialogoGrafica.newInstance();
dialogoGrafica.show(((Activity)mContext).getSupportFragmentManager());
}
}
///DialogFragmen.class
public class DialogoGrafica extends DialogFragment {
public static DialogoGrafica newInstance() {
return new DialogoGrafica();
}
}
The problem is here:
dialogoGrafica.show(((Activity)mContext).getSupportFragmentManager());
in the adapter when call .show()
what can i do?
I think you need to say to the DialogoGrafica What fragment you want to be shown. Something like this:
((Activity)mContext).getSupportFragmentManager().findFragmentByTag("Your Fragment Name")
you can do it by using a listener
add this interface to your adapterAdaptadorEncuesta
public interface OnClickedListener {
public void onItemClicked();
}
and then adapter constructor should look like this
OnClickedListener mListener;
public AdaptadorEncuesta(OnClickedListener listener) {
mListener = listener;
}
in the activity when you initialise the adapter
AdaptadorEncuesta adapter = new AdaptadorEncuesta(this)
pass this and implements the interface in you activity
then when you press or call on click in the adapter you will call the method onClick() and inside the OnClick() you will call the listener like that to run the onItemClicked() method in the activity
mListener.onItemClicked();
then method onItemClicked() on your activity will run that you have been do implements for his interface
now still to show the dialog inside the method
#Override
public void onItemClicked(View view) {
dialogoGrafica.show(((Activity)mContext).getSupportFragmentManager());
}
You didnt told the problem, but I suppose it is no method found exception for getSupport...
The method is for the AppCompatActivity not the Activity.
So replace to:
((AppCompatActivity)mContext).getSupportFragmentManager()
I have two fragments (each a tab in a sliding tab activity) in my application. The two fragments have some methods which now are identical, I thought that I could abstract out those methods to follow the DRY (don't repeat yourself) principle. Is there any recommended way of doing this?
Is a util class with static methods a good way? Or should I create an abstract class "MyAbstractFragment" which has those methods and let the fragments extend this class?
For example.
public class MyCustomFragment extends Fragment {
protected LinearLayout linearLayout;
protected MyAdapter adapter;
//more common fields
void addButtonToFragmentView(final String btnText) {
final Button btn = new Button(getContext());
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
linearLayout.removeView(btn);
}
});
btn.setText(btnText);
linearLayout.addView(btn);
}
void upDateAdapterList(List<String> list){
//....
adapter.updateList(list);
}
}
Than my fragments could extend this class and set the properties and use the methods. But I also see that I as well could make a static util class just for the methods, like addButtonToFragmentView(final String btnText, Context context, final LinearLayout linearLayout) and upDateAdapterList(List<String> list, MyAdapter adapter)
Or is there a preferred way of doing this?
Yes, you can use abstract class like below:
public abstract class BaseFragment extends Fragment {
#Override public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
public Context getContext() {
return this.getActivity().getApplicationContext();
}
protected abstract void addButtonToFragmentView(final String btnText);
protected abstract void upDateAdapterList(List<String> list){
}
then extends your new fragment with this base class.
code taken from:
https://github.com/spirosoik/AndroidArchitecturePadawans/blob/master/presentation/src/main/java/com/architecture/padawans/views/common/BaseFragment.java
We should try to follow composition over inheritance. May be you can have a dedicated UIFactory class which deals with dynamic creation of views, then you move your addButtonToFragmentView method to the UI factory and make if more generic.
void addButtonToView(final String btnText, final Context, final View parentView);
As far as upDateAdapterList is concerned you can create a BaseListFragment and move it there, so whoever is interested in using a fragment with List can extend this Fragment. Hence this follows Single Responsibility Principle.
In my main Activity, I have a DialogFragment that contains a FragmentTabHost. I have two tabs, one that is a DialogFragment and one that is a ListFragment. When either the 'OK' button is pressed in the inner DialogFragment or when an element in the ListFragment is pressed, I want to pass two Strings (that are entered in two TextView's in the inner DialogFragment and are displayed in each element in the ListFragment) back to the Activity, but I am unsure of how to do this with multiple levels of Fragments.
Any help is appreciated!
There's no magic.
You can achieve with two approaches.
Use callback.
Create interface and class to pass the data through child Fragment to Activity. You don't need to modify bridged TabHostFragment as Fragment always rely on its mother Context (Activity) no matter how many fragments wrap the fragment.
public class TwoStrings {
public TwoStrings(String one, String two){
this.one = one;
this.two = two;
}
public String one;
public String two;
}
First, declare interface.
public interface DataPassListener {
void dataPassed(TwoStrings data);
}
And, implement interface in Activity.
public class MainActivity extends Activity implements DataPassListener {
#Override
public void dataPassed(TwoStrings data) {
// do something with data.
Log.d("string one", data.one);
Log.d("string two", data.two);
}
}
Finally, let child Fragment acknowlege that mother Activity has the callback listener.
public class DialogFragment1 extends DialogFragment {
DataPassListener listener;
#Override
public void onAttach(Activity activity) {
if (activity instanceOf DataPassListener)
listener = (DataPassListener) activity;
}
public void setDataPassListener(DataPassListener listener){
listener = ((DataPassListener) listener);
}
public void doSomeThing(){
if(listener != null) // important to prevent NullPointerException
listener.dataPassed("a", "b");
}
}
Use EventBus.
I prefer to use Otto in order to publish and subscribe data.
To subscribe event for listening in Activity,
public class MainActivity extends Activity {
#Override
public void onResume() {
super.onResume();
BusProvider.getInstance().register(this);
}
#Override
public void onPause() {
super.onPause();
BusProvider.getInstance().unregister(this);
}
#Subscribe
public void onUpdateTwoStrings(TwoStrings event) {
// do something with data.
Log.d("string one", data.one);
Log.d("string two", data.two);
}
}
And, publish event in anywhere in Fragment.
bus.post(new TwoStrings("a", "b"));
Take a look at setTargetFragment() and getTargetFragment() methods. You could connect fragments with each other through it without any additional callbacks and libs.
I have an activity that contains listview, inside listview rows i have a checkbox in each row. every time i check or uncheck the checkbox the activity should listen immediately and knows how many rows is checked or unchecked, how do I implement it in android? thanks before
You should create Listener like below.
interface CheckBoxCleckListener{
void OnCheckboxClicked();
}
Define above code in your adapter class or other.
Now whenever you want to call it, write following code in your Adapter class.
//this will create object of listener
public static CheckBoxCleckListener checkBoxCleckListener;
You need to initialized it by your caller class which is your Activity in your case.
public static void addListener(
CheckBoxCleckListener listener) {
checkBoxCleckListener= listener;
}
Now, whenever your check box clicked, write following code inside,
checkBoxCleckListener.OnCheckboxClicked();
In your activity class, write following code,
public class YourActivity extends Activity implements CheckBoxCleckListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
//rest of code
YOUR_CLASS_WHERE_INTERFACE_IMPLEMENTED.addListener(this);
}
#Override
public void OnCheckboxClicked() {
//do your coding
}
}
Im using supportApi for lower versions. I have a listFragment and an asynchAdapter which loads data in background from web. The problem is if the data is changed in Background I cant make the listFragment to refresh and show the new data. I have a customListAdapter that extend baseAdapter and I am calling setlistadapter(customListAdapter) in my ListFragment. I need some example which implements something like this not the cursorAdapter or simpleArrayAdapter.
The only problem I have is I dont know how to refresh the listFragment as onResume doesnt gets called and not sure if notifydatasetchange will work on listfragment. Some pieces of my code is as follow.
the onLoadFinish gets call only once when I initialize loader. The onresume gets called only once as well. May be my approach is wrong but that what I am not sure about.
public class MyListFragment extends ListFragment implements LoaderManager.LoaderCallbacks<ArrayList<MyData>> {
private ArrayList<MyData> mydata;
private CustomListAdapter adapter;
#Override public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
this.adapter = new CustomListAdapter(this.getActivity(), mydata);
setListAdapter(this.adapter);
getLoaderManager().initLoader(0, null, this);
}
#Override
public void onLoadFinished(Loader<ArrayList<MyData>> Loader, ArrayList<MyData> mydata) {
this.adapter.setData(mydata);
}
}