I have a simple MyListFragment fragment which shows one simple array of data on the screen.
public class MyListFragment extends ListFragment {
private ArrayAdapter<String> adapter;
public ArrayAdapter<String> getAdapter() {
return adapter;
}
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
String[] values = new String[] {"data", "data", "data"};
adapter = new ArrayAdapter<String>(getActivity(),
android.R.layout.simple_list_item_1, values);
setListAdapter(adapter);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return super.onCreateView(inflater, container, savedInstanceState);
}
}
I wonder how can I change this data dynamically from my Activity? Please tell me if there is a simple way how to do this! I've tried but have failed...
UPD: I added a function changeContent to MyListFragment:
public void changeContent(String[] value) {
adapter.addAll(value);
adapter.notifyDataSetChanged();
}
}
As you see, adapter is a global variable and it's initialized inside onActivityCreated, but my program crashes because inside changeContent in equals null! I can't get why!
You could write a function that changes your values variable and then once you have filled it with your new data just call
adapter.notifyDataSetChanged();
to fill your list with the new data.
Related
I have MainActivity,which contain viewpager,which contain 2 fragments:
MainActivity
ViewPager viewPager = findViewById(R.id.viewPager);
MyPagerAdapter adapter = new MyPagerAdapter(this,
getSupportFragmentManager());
viewPager.setAdapter(adapter);
TabLayout tabLayout = findViewById(R.id.TabLayout);
tabLayout.setupWithViewPager(viewPager);
Fragment fragmentHour=adapter.getItem(1);
onChangeDayListener2= (OnChangeDayListener) fragmentHour;
I am also have interface for send data from main activity in fragment:
public interface OnChangeDayListener{
void OnChange(WeatherList list,int pos);
}
but when i try to work with this callback in interface my recycler adapter always is null:
HourWeatherFragment:
public class HourWeatherFragment extends Fragment implements MainScreen.OnChangeDayListener{
private RecyclerView recyclerView;
private AdapterHour adapter;
private ArrayList<Weather> days;
Context context;
static HttpClient httpClient;
public HourWeatherFragment() {
// Required empty public constructor
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
days=new ArrayList<>();
adapter = new AdapterHour(days,getActivity());
LinearLayoutManager LayoutManager = new LinearLayoutManager(getActivity().getBaseContext(),
LinearLayoutManager.VERTICAL, false);
recyclerView.setLayoutManager(LayoutManager);
recyclerView.setAdapter(adapter);
days.add(new Weather());
recyclerView.getAdapter().notifyDataSetChanged();
Log.d("recycler","adapter seted!");
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.fragment_hour_weather, container, false);
recyclerView = rootView.findViewById(R.id.hour_list);
httpClient=new HttpClient();
MyAsyncTask task=new MyAsyncTask();
// task.execute("lviv");
return rootView;
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
this.context=context;
}
#Override
public void OnChange(WeatherList list,int pos) {
String date=list.getAverageWeather().get(pos).getDate();
ArrayList<Weather> weather=list.getByDate(date);
Log.d("ldata","size of weather for adding="+weather.size());
// days.add(new Weather());
if(adapter!=null){
adapter.notifyDataSetChanged();
Log.d("tag","first null!");}
else{
try{
recyclerView.getAdapter();}
catch (NullPointerException ex){
Log.d("tag","null!");//THERE ALWAYS NULL
}}
So,firstly creating activity,then i start load data and when data loaded i send data from MainActivity to HourWeatherFragment throught callback,
but when i receive data in fragment,my adapter is null,how i can fix it?
You can create a static singleton class to hold data and retrieve that data in the fragment.
public class DataHolder {
//create static variables here.
}
In your fragment simply retrieve the data and make it null after that.
Alternative solution
Another solution is to use Bundles. Follow the bundle solution here.
You must cast RecyclerView.
in your fragment and onCreateView method :
recyclerView = (RecyclerView) rootView.findViewById(R.id.hour_list);
I know this is an old question, but contrary to the accepted answer I think the issue is that the handle to the fragment's widget such as recyclerView is not available in the OnCreateView function.
The handles (or pointers if you wish) to the widgets are only guaranteed to exist in the OnViewCreated function.
This documentation has good description of the lifecycle of fragments:
https://guides.codepath.com/android/Creating-and-Using-Fragments
an extract is:
// This event is triggered soon after onCreateView().
// onViewCreated() is only called if the view returned from onCreateView() is non-null.
// Any view setup should occur here. E.g., view lookups and attaching view listeners.
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
ListView lv = (ListView) view.findViewById(R.id.lvSome);
lv.setAdapter(adapter);
}
Hope this helps.
I am building an android application containing 4 tabs, each containing a fragment attached to cursor adapter. Each fragment contains a list of items.If I scrolled a lot down in any list, I have to scroll a lot back to get to the top.I want the it to behave like this: when I click on the current tab icon, it will automatically scroll back to top. How can I implement this functionality?
edit 1:
this is how the it is implemented:-
public class OutboxFragment extends ListFragment implements LoaderManager.LoaderCallbacks<Cursor> {
OutboxListAdapter mAdapter;
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mAdapter = new OutboxListAdapter(getActivity(),R.layout.outbox_list_item, null, 0);
setListAdapter(mAdapter);
getLoaderManager().initLoader(0, null, this);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_outbox, container, false);
return view;
}
On tab changed you can refresh your list view:
MyAdapter myAdapter = new MyAdapter(mContext, items);
mListView.setAdapter(myAdapter);
mListView.setSelection(0);
Instead of setting a new adapter (which causes ListView to reset its state), simply update the content of the adapter already set on the ListView.
You can create a refill() method to your adapter:
public void refill(List<EventLog> events) {
mEvents.clear();
mEvents.addAll(events);
notifyDataSetChanged();
}
And call it onTabChanged:
if (mListView.getAdapter() == null) {
MyAdapter myAdapter = new MyAdapter(mContext, items);
mListView.setAdapter(myAdapter);
} else {
((MyAdapter)mListView.getAdapter()).refill(items);
}
based on your problem you need to scroll the fragment list to the top. you can do this by calling following function:
getListView().smoothScrollToPosition(0);
which getlistView returns your fragment ListView;
My listview gets filled on the start but after i cant find a way to make changes
pls see the code bellow
public class myFragment extends android.support.v4.app.Fragment
{
ListView list;
ArrayList<String> restorants=new ArrayList<String>();
Manager m=new Manager();
ArrayAdapter<String> adapter;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_, container, false);
list=(ListView) rootView.findViewById(R.id.myList);
for(Restorant r : m.getResByCity("nyc"))
{
restorants.add(r.getName());
}
adapter=new ArrayAdapter<String>(getActivity(), R.layout.item_list, R.id.restorantItem,restorants);
list.setAdapter(adapter);
return rootView;
}
public void makeChange(String s)
{
restorants.remove(0);
((ArrayAdapter)list.getAdapter()).notifyDataSetChanged();
}
}
While calling the method makeChange() i have checked that the restorants items are removing so that there is no problem with calling the method
makeChange() is called from my mainActivity that contains viewpager where this fragment is contained in the viewpager.
you need to remove the element from the dataset you provided to the adapter,
adapter.remove(s)
Here you can find the documentation
Here's the code that's producing unexpected results. If anyone can please guide me to what I'm doing wrong here
public static class LaunchpadSectionFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_section_launchpad, container, false);
ListView moviesList= (ListView) rootView.findViewById(R.id.movies_list);
ArrayAdapter<String> moviesAdapter;
List<String> Testing = new ArrayList<String>();
Testing.add("Hey");
Testing.add("Hey");
Testing.add("Hey");
Testing.add("Hey");
moviesAdapter= new MyAdapter(getActivity(),android.R.layout.simple_list_item_1,Testing);
moviesList.setAdapter(moviesAdapter);
return rootView;
}
Ok after playing around a Lot going through documentation I finally found a workaround to this.
This is what I did
#Override
public void onActivityCreated(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);
super.onActivityCreated(savedInstanceState);
Log.d("CreatedActivity", "LaunchpadFragment");
ListView moviesList= (ListView) getActivity().findViewById(R.id.movies_list);
// Gets the ListView from the View list of the parent activity
// Gets a CursorAdapter
ArrayAdapter<String> moviesAdapter;
List<String> Testing = new ArrayList<String>();
Testing.add("Hey");
Testing.add("Hey Do");
Testing.add("Hey It");
Testing.add("Hey Please");
moviesAdapter= new ArrayAdapter<String>(getActivity(),android.R.layout.simple_list_item_1, Testing);
moviesList.setAdapter(moviesAdapter);
}
Note the over-ridden method here, it is
onActivityCreated
Android documentation states
If your view of the fragment is a listview that is being filled by a data adapter, you should override the onActivityCreated method and do the filling in there.
I don't have a documentation link to this blockquote though:|
I want a custom row, so I am using a List View in an xml and inflating into a fragment. I am very confused of how to set the adapter for the list View.
I created a new adapter which extends Base Adapter. In the getView method, I really don't know what context to pass while inflating the row.xml layout.
How do I set the adapter for the list view and where?
public class ResultsFragment extends Fragment{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.results_layout, container, false);
listView = (ListView)v.findViewById(R.id.results);
return v;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
loadPage(dataBean.getWhat(), dataBean.getWhere(), dataBean.getPageStart());
//resultsAdapter.setRssData(rssData);
//setListAdapter(resultsAdapter);
}
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
Context context = getActivity().getApplicationContext();
resultsAdapter = new ResultsAdapter(context);
}
/**
* Set List Adapter
*/
private void setAdapter(){
if(listView.getAdapter() == null){
listView.setAdapter(resultsAdapter);
}
else{
resultsAdapter.notifyDataSetChanged();
}
}
}
You must extend Listfragment (instead of Fragment), and using its ListFragment.setListAdapter to set your adapter. In the adapter getView() inflate your row.. that s all
If you do not want to change your extended class, you should use listview.setAdapter(...) method. As you see in my example :
ListView productList= (ListView) getActivity().findViewById(R.id.product_list);
SampleAdapter adapter = new SampleAdapter(getActivity());
adapter.add(new SampleItem(
"Sunny LCD TV 2\" SN022L66-T1 Full HD",
R.drawable.product_sample_pic);
productList.setAdapter(adapter);