I used PagerSlidingTabStrip and have to fragments.
In each fragments, I used AsyncTask to get data from server.
Below is my fragment class that gets html from server and displays listview.
public class MainFragmentSubList extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_main_list, container, false);
ListView mainList = (ListView) view.findViewById(R.id.fragment_list);
ArrayList<String> infoList;
// this is AsyncTask class and i made an interface.
new GetHtml(new OnRequestFinish(){
#Override
void onFinish(){
// Below are about ui
ArrayList<String> titleList = (ArrayList<String>) User.subName.clone();
int size = infoList.size();
MainListAdapter adapter = new MainListAdapter(titleList, infoList, size + 1);
mainList.setAdapter(adapter);
}
}).execute();
return view;
}
Since AsyncTask does things in background, return view; didn't work as I expected.
Here is my main activity that has fragments.
public class MainActivity extends ActionBarActivity {
private Context context;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
pager = (ViewPager) findViewById(R.id.pager);
pager.setAdapter(new MyPagerAdapter(getSupportFragmentManager()));
PagerSlidingTabStrip tabs = (PagerSlidingTabStrip) findViewById(R.id.tabs);
tabs.setShouldExpand(true);
tabs.setViewPager(pager);
}
}
How can I return View from fragment using AsyncTask?
Go ahead and setup your view in onCreateView. Init and set your adapter too, with an empty list. For convenience you make the adapter and your list member variables.
Make sure that onFinish is invoked by AsyncTask's onPostExecute, so that it runs on the correct thread. When it is called, you update your list and then call the adapter's notifyDataSetChanged() method.
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 have an ActionBar that has 2 tabs and each tabs layout is a fragment. in 1 of these tabs , there is a listView. and i want to set ArrayAdapetr for it. but when i run app, error occurred and error is about my application context. my code is :
public class TarfandFrag extends Fragment {
String values[] = new String[]{"sadeq","ali"};
ListView listView;
Context context;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.tarfad_layout,container,false);
listView = (ListView) view.findViewById(R.id.list_tarfand);
return view;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ArrayAdapter adapter = new ArrayAdapter(context,android.R.layout.simple_list_item_1,values);
listView.setAdapter(adapter);
}
}
but its not working. notice that i don't want use listFragment or anything else. i replace context with getActivity() , context.getApplicationContext, getActivity.getApplicationContext. but not working. plz help meeeee
Assing getActivity() to context in onCreate.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
context=getActivity();
}
In a fragment, onCreate() is called before onCreateView(). the consequence of this is that, at the point onCreate() is called, your ListView is not yet associated with an element in the layout (as your are doing this in onCreateView() which gets called later) and will hence resolve to null and you will get a null pointer exception when you set the adapter for the ListView. Move the code setting the adapter to within the onCreateView() method and use getActivity() and you should be fine.
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.tarfad_layout,container,false);
listView = (ListView) view.findViewById(R.id.list_tarfand);
// Here listview will not be null as it is now bound to an object
ArrayAdapter adapter = new ArrayAdapter(getActivity(),android.R.layout.simple_list_item_1,values);
listView.setAdapter(adapter);
return view;
}
I have an app with ViewPager that contains 4 Classes extends Fragment. i've follow tutorials on internet, but now i have occurred in a strange problem.
This is constructor of fragment adapter:
public class FragmentAdapter extends FragmentPagerAdapter {
private final int PAGE_COUNT = 4;
TableFragment table_fragment;
MixFragment mix_fragment;
HumFragment hum_fragment;
TempFragment temp_fragment;
public FragmentAdapter(FragmentManager fm) {
super(fm);
Log.i("AAAAAA", "FragmentAdapter constructor");
table_fragment = new TableFragment();
mix_fragment = new MixFragment();
hum_fragment = new HumFragment();
temp_fragment = new TempFragment();
}
and this is one of the fragment compose ViewPager (the others look similar):
public class TableFragment extends Fragment {
MainActivity main;
ListView list_view;
ArrayAdapter<String> adapter;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.tab_layout, container, false);
list_view = (ListView) v.findViewById(R.id.list_view);
adapter = new ArrayAdapter<String>(v.getContext(),
android.R.layout.simple_list_item_1);
list_view.setAdapter(adapter);
return v;
}
Now, i've noticed that, after in my mainactivity i create a new FragmentAdapter object, the onCreateView() method of fragment isn't call immediatly, and my app crash (because each fragment have some methods that modify the fragment content).
How can i do for avoid this? i need that Fragments are created immediatly, so i can perform action on its
I have the following code for my fragment. I pretty much took this from a basic view pager example and slapped it into a fragment to test for a project I'm working on.
I'm using ACtionBarSherlock, and viewPagerIndicator libraries. The Fragment below contains a viewPager that in this example is supposed to swipe between simple title strings.
I tried the example with the ViewPager and ViewPagerIndicator in an activity, and no problem. But the second I put it into a fragment. BOOM, nothing but a black screen... NO errors, just a black screen...I feel like I must be inflating, or accessing the layout incorrectly or something...
Any ideas?
Here's the code:
public class TestFragment extends SherlockFragment {
//~Constants----------------------------------------------
//~Data Fields--------------------------------------------
//~Constructors--------------------------------------------
#Override
public void onCreate(Bundle savedInstanceState) {
//Setup view
super.onCreate(savedInstanceState);
View view = onCreateView(getLayoutInflater(savedInstanceState), null, savedInstanceState);
ViewPagerAdapter adapter = new ViewPagerAdapter( this.getSherlockActivity() );
ViewPager pager =
(ViewPager)view.findViewById(R.id.free_time_day_pager);
TitlePageIndicator indicator =
(TitlePageIndicator)view.findViewById(R.id.titles);
pager.setAdapter( adapter );
indicator.setViewPager( pager );
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.free_time_fragment_layout, null, false);
return view;
}
//~Methods-------------------------------------------------
}
Dont call onCreateView that is wrong.
onCreateView is an overridden method which is called by the FragmentManger to handle the Fragment lifecycle.
private ViewPager mViewPager;
private TitlePagerIndicator mIndicator;
// Called first
#Override
public void onCreate(Bundle savedInstanceState) {
//Setup view
super.onCreate(savedInstanceState);
}
// Called second
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.free_time_fragment_layout, null, false);
return view;
}
// Called third
#Override
public View onViewCreated(View v){
super.onViewCreated(v);
mViewPager = (ViewPager) v.findViewById(R.id.free_time_day_pager);
mIndicator = (TitlePageIndicator)v.findViewById(R.id.titles);
}
public void onActivityCreated(Bundle bdl){
super.onActivityCreated(bdl);
ViewPagerAdapter adapter = new ViewPagerAdapter( getSherlockActivity() );
mViewPager.setAdapter(adapter);
mIndicator.setViewPager(pager);
}
Also be aware if you are using a FragmentPagerAdapter you require a special method to create the ViewPagerFragment, its a bit tricky but refer to this gist.
Read about Fragment Lifecycles here too.
Cheers
Use this.
compile 'com.android.support:appcompat-v7:23.0.1'
work for me.
i dont know where can i put the code to start a fragment. I have a viewpager with fragments but they dont do nothing. For example:
I have the class fragmentosactivity thats inicialize de fragments:
public class FragmentosActivity extends FragmentActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
super.setContentView(R.layout.fragmentos_layout);
// Paginador
this.inicializaPaginas();
//ActionBar
ActionBar actionBar = getSupportActionBar();
actionBar.setTitle("Contoles");
//CirculoProgreso
setProgressBarIndeterminateVisibility(Boolean.FALSE);
}
//Este metodo inicia todos los fragments
private void inicializaPaginas() {
FragmentAdapter adapter =
new FragmentAdapter(getSupportFragmentManager());
adapter.addFragment(new Mapa());
adapter.addFragment(new Cercanos());
ViewPagerAdapter vadapter = new ViewPagerAdapter( this );
ViewPager pager =
(ViewPager)findViewById( R.id.viewpager );
TitlePageIndicator indicator =
(TitlePageIndicator)findViewById( R.id.indicator );
pager.setAdapter( adapter );
pager.setAdapter( vadapter );
indicator.setViewPager( pager );
}
}
Here i call cercanos.class
And in cercanos i have
public class Cercanos extends ListFragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if (container == null) {
return null;
}
return (LinearLayout) inflater.inflate(R.layout.cercanos, container, false);
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String[] objetos = {"hola","adios"};
setListAdapter(new ArrayAdapter<String>(getActivity(),
android.R.layout.simple_list_item_1, objetos));
Parseador.anadedatos();
}
}
But never enter in onCreate method of cercanos, why? I think i dont understand for all the use of fragments.
this is called only in main activity, not in views
public class XXX extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
....
}
}
onCreate is a fragment of the application life-cycle, not class or view life-cycle
You can try to overriding this method:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
And put the onCreate code here.
Anyway, you can take a look at the documentation, because fragments don't have a setContentView, is in the xml layout where you tell what fragment controlls the layout. http://developer.android.com/guide/topics/fundamentals/fragments.html
Hope this helps