I have an adapter class and calling startActivityForResult() and getting the result in my Activity where I am using the adapter.
I want to change the image view background on getting the result.And the change should effect only the particular position of the RecyclerView.
startActivityForResult() inside the adapter class:
pass the context to your adapter class and do this:
((Activity)context).startActivityForResult(...);
As far as updating the RecyclerView, you can get the position inside the onBindViewHolder() and just update the class object from the List or ArrayListfor the image and call notifyDataSetChanged() after that.
P.S. this is the best I can do to explain to you without any code.
Edit : to get the TextView from the adapter class inside the Activity class:
View viewItem = recycleView.getLayoutManager().findViewByPosition(position);
TextView textView = viewItem.findViewById(R.id.textView);
textView.setTextColor(getResources().getColor(R.color.yourColor));
Related
Here is my scenario: In my application i have a Main activity, two fragments and a service that runs in background. I attach the fragments to my main activity using this piece of code:
Fragment f1;
f1=new loginfragment();
FragmentTransaction ft=getFragmentManager().beginTransaction();
ft.add(R.id.frame,f1);
ft.commit();
Which is working fine. one of these fragments contains a listview which is attached to an adapter.(i have verified that adapter is correctly attached to the listview and entries can be added to listview without any problems.
In order to be able to inflate a layout inside the listview adapter(which extends BaseAdapter) i created a constructor to feed Context to it.
background service checks a page periodically and sends the results to one of these fragments using an interface that the fragment implements(sending broadcasts didn't work for me).interface is defined like this:
interface resultInterface{
void receive(String s,Context con);
}
fragment implements the interface like this:
#Override
public void receive(String s,Context con){
String elements[]=s.split("<br>");
if(elements.length>1) {
if(elements[0].equals("REQUEST")) {
init_notification("REQUEST",detect(elements[1],elements[2]));// a function that shows a notification
item i = new item(elements[1], elements[2]);
orders.add(i);
adapter = new listview_adapter(orders,c);
list.setAdapter(adapter);}
}
}
orders is an Arraylist and c is the context that is being passed to the listview adapter. service calls this interface method like this:
resultInterface resultinterface=new servefragment();
resulstinterface.receive(s,this);
upon receiving data (which results in calling the interface method) the fragment method is supposed to split the data and add entries to the listview.(i have verified that data is being correctly passed to the interface method.
BUT, the view that is being shown as listview entries is not correct( look corrupted somehow). Here is how it is supposed to look(using dummy data):Like this but here is how they are actually added(1 item is received from server which is correct but the layout is not): Like this
If you need more information just comment and i'll add them
My guess is that the Context object your service is passing to you has a different theme than you're expecting. This can cause text colors, button colors, etc to all change.
In order to be able to inflate a layout inside the listview adapter(which extends BaseAdapter) i created a constructor to feed Context to it.
Unless you need the Context instance somewhere other than inside getView(), you don't have to pass a Context via a constructor. Here's the full signature of the getView() method:
public View getView(int position, View convertView, ViewGroup parent)
The parent argument is guaranteed to be non-null, and all View instances have a getContext() method, so you can always retrieve a Context by writing parent.getContext(). Additionally, this will be your Activity (as opposed to something like your Application), which has the added benefit of having the correct theme.
So delete all of the code that passes the Context into your adapter and just use parent.getContext() instead, and I bet the problem goes away.
I have a nested Fragment with a Viewpager inside of it. I'm trying to access a method (using MainActivity) in one of the Viewpager's Fragments, but I only get the last Viewpager Fragment or can't access methods when I use
ProfileFragment f = (ProfileFragment) getSupportFragmentManager().findFragmentById(R.id.fragmentLayout);
...
Fragment f = v.getChildFragmentManager().findFragmentById(R.id.pager);
// Doesn't even work when I use findFragmentByTag("TAG")
where 'fragmentLayout' is the container for my Fragment Transactions inside activity_main.xml. (Currently ProfileFragment inside)
Here is how I nested my Fragments/xml:
MainActivity
- fragmentLayout
- ProfileFragment (or LoginFragment/ChatFragment/ShopFragment/etc)
- xml items
- viewPager
- Fragment1
- Fragment2 // can't access methods in here from MainActivity
- navigationTabs
I tried getting the Viewpager & PageAdapter from ProfileFragment and it shows the correct number of fragments, but I can't seem to access the methods.
Would an interface be something to look into? Or is there an easier way? Thank you.
String tag = makeFragmentName(mViewPager.getId(), getItemId(position));
Fragment fragment = getSupportFragmentManager().findFragmentByTag(tag);
return fragment;
((YourFragment)fragment).methodName();
Try this
There are 2 simple ways to do it:
Store your Fragment1 and Fragment2 in your ProfileFragment, then when you need to call there's function, just call fragment1.doSomeThing() from your ProfileFragment. This approach is ok when your ViewPager's adapter dont have too many fragments (in this case, you should use WeakReference to avoid OOM when storing your fragments`.
Using EventBus (or LocalBroadCastReceiver, but I prefer EventBus). Then you can call your doSomeThing() function from anywhere, with the call like below:
EventBus.getDefault().post(new CallYourFunctionObject(int value)
None of the solutions worked for me & I had trouble implementing an interface with my nested fragments.
I ended up putting the methods in MainActivity which was the easiest solution for me.
I can also access the nested fragment views directly from MainActivity with
TextView tv1 = findViewById(R.id.exampleid);
I've got an Application with a MainActivity with a Navigation Drawer MenĂ¹.
Inside the MainActivity View I've got a Frame layout which takes the whole space.
When the user select something from the menĂ¹ I call a method which handle the fragments transaction inside the Frame Layout.
My MainActivity is the Fragment manager and from here i can handle all the changes I want and i can handle the communications between the fragments.
Here's the problem:
In one of my Fragment i'd like to show 2 new fragments, one with a PieChart and one with the data.
I could have done only one Fragment with all inside its view but i'd like to use a modular managing way.
So, first of all i created 1 fragment, the Container one (we can call it A).
In its view i put the fragment B and fragment C, directly from Xml.
In fragment B i've got the PieChart, HERE i call the methods to download data from a database, and then i put this data inside the chart.
I wrote a simple Interface which contains a method which is called when the user interact wich the chart; it build an object whith the selected data.
My target is to send this data to Fragment A and then pass them to Fragment C, so that the user can see what is he selecting.
In Fragment A i've Implemented the Fragment B inteface, then i set up this code inside OnAttach of B:
#Override
public void onAttach(Context context) {
super.onAttach(context);
try {
Interface = (InterfaceB) context;
} catch (ClassCastException e) {
throw new ClassCastException(context.toString()
+ " must implement InterfaceB");
}
}
Everithing seems to works, but in the moment tha Fragment A is created, OnAttach of B is called, and the context which arrives refers to MainActivity and not to Fragment A.
This causes a Crash.
Fragment is not an instance of Context, so it is impossible to pass it to onAttach(Context Context) anyway.
There are two ways how you can do what you want.
1) Use onAttachFragment(Fragment fragment) inside fragment A, and catch events when fragments B and C are attached;
2) Use getParentFragment() inside fragments B and C, to access A.
How can I reference an adapter within onCreateOptionsMenu, when the adapter is created inside OnPostExecute?
Within onCreateOptionsMenu I have two methods:
onQueryTextChange
onQueryTextSubmit
In each I use adapter.getFilter().filter(newText);.
What's the issue:
My adapter can not be assigned and used with getFilter() due to the structure of my code.
Because my my adapter is created within:
Class LoadInbox extends AsyncTask Protected String doInBackground OnPostExecute -> Created here
How can I reference my adapter within onPostExecute to work within onCreateOptionsMenu
I have a listview NoteList which contains a method doListRefresh() to select list contents from the sqlite note table, populates a cursor (which populates my array adapter), then calls adapter.notifyDataSetChanged(); to refresh the list. Upon (add, edit, deletes etc)
Inside my custom Array adapter i populate several elements on each row including a delete button. Inside the array adapter i have the delete button onClick handler etc. I need to call NoteList.doListRefresh() from within my Array adapter and i do this by using a setter inside my array adapter which is called from NoteList something like adapter.setNoteListObj(this);. This is working but i'm not sure its the best way?
I wanted to ask if this is "best practice" for doing something like this?
Thank you for any advice
Here is some of the sample code:
Within NoteList:
onCreate(Bundle savedInstanceState) {
thisObject = this;
}
// set custom ArrayAdapter to the data
adapter = new NoteArrayAdapter(activity, R.layout.channel_note_list_item, noteList);
adapter.setNoteList(thisObject);
...
within Adapter:
private NoteList callingNoteListObj;
...
// setter
protected void setNoteList(NoteList _callingNoteListObj) {
this.callingNoteListObj = _callingNoteListObj;
}
...
// within delete onclick handler (after delete)
// refresh local database
callingNoteListObj.doListRefresh();
I don't see why not. All you are doing is passing a reference to the instance (a "pointer" for those who have done more than Java). Personally, I'd pass this into the constructor for your adapter and store the reference locally. In fact, you probably already do if you pass in this as a Context object in order to construct an ArrayAdapter. Since its your custom adapter for your custom NoteList, you could very well just cast context (or this.getContext()) to NoteList and call it without needing to use a setter.