This question already has answers here:
Passing Data Between Fragments to Activity
(7 answers)
Closed 5 years ago.
I am new to Java. The activity is to receive an ID and reuse that ID to get the detail of the recipe with a Recipe API. I am using three tabs to show different content. The problem that I could not figure out is that the first (description tab) and the third (step tab) can receive the string from main activity, but the second tab (ingredient tab) always receives null value from the main activity. Also, The string does not show on the first tab immediately when I run the activity. It only shows after I click on the third tab and come back to the first one.
Activity
public class SearchHomeResultActivity extends AppCompatActivity {
private SectionsPagerAdapter mSectionsPagerAdapter;
private ViewPager mViewPager;
public String RecipeId = "479101";
public String SInstruction;
public String SIngredients;
public String STitle;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search_result);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mViewPager));
new CallMashapeAsync().execute(RecipeId);
}
public class CallMashapeAsync extends AsyncTask<String, Integer, HttpResponse<JsonNode>> {
protected HttpResponse<JsonNode> doInBackground(String... msg) {
HttpResponse<JsonNode> request = null;
try {
request = Unirest.get("https://spoonacular-recipe-food-nutrition-v1.p.mashape.com/recipes/" + msg[0] + "/information")
.header("X-Mashape-Key", "EulyPgSat2mshhTi8JJxY40UEWzdp1mMmEGjsnrbQq1AB0vuOY")
.header("X-Mashape-Host", "spoonacular-recipe-food-nutrition-v1.p.mashape.com")
.asJson();
} catch (UnirestException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return request;
}
protected void onProgressUpdate(Integer... integers) {
}
protected void onPostExecute(HttpResponse<JsonNode> response) {
String answer = response.getBody().toString();
try {//get all response
JSONObject obj = new JSONObject(answer);
//get ingredients
String Ringredient = obj.getString("extendedIngredients");
List<String> terms1 = new ArrayList<String>();
JSONArray ing = new JSONArray(Ringredient);
for (int i = 0; i < ing.length(); i++) {
JSONObject ING1 = ing.getJSONObject(i);
String Ostr = ING1.getString("originalString");
terms1.add(Ostr);
}
String listString = "";
for (String s : terms1) {
listString += s + "\n";
}
//get instructions
String Rid1 = obj.getString("instructions");
//get title
String Rid2 = obj.getString("title");
SInstruction = Rid1;
SIngredients = listString;
STitle = Rid2;
} catch (JSONException e) {
throw new RuntimeException(e);
}
}
}
public String getIns() {
//
return SInstruction;
}
public String getIngredients() {
//
return SIngredients;
}
public String getRTitle() {
//
return STitle;
}
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
descriptionTab tab1 = new descriptionTab();
return tab1;
case 1:
IngredientsTabActivity tab2 = new IngredientsTabActivity();
return tab2;
case 2:
StepTabActivity tab3 = new StepTabActivity();
return tab3;
}
return null;
}
#Override
public int getCount() {
// Show 3 total pages.
return 3;
}
}
}
Fragment
public class StepTabActivity extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState){
View rootView = inflater.inflate(R.layout.step_layout, container, false);
SearchHomeResultActivity getData = (SearchHomeResultActivity) getActivity();
String Rid = getData.getIngredients();
TextView txt = rootView.findViewById(R.id.name);
txt.setText(Rid);
return rootView;
}
This is the code of the Step (the third) fragment. Other two are the same, but just calling different methods to get different strings for the TextView.
Please help me. Thank you so much!
You can create a constructor like method called newInstance in your fragment as below,
public static FragmentName newInstance(String str) {
Bundle args = new Bundle();
FragmentName fragment = new FragmentName();
fragment.setArguments(args);
resID = str;
return fragment;
}
define your "resID" as global variable and use it in fragment's onCreate method.
and from activity when u are adding fragment to viewPager adapter do like this
adapter.addFrag(FragmentName.newInstance(resID), "fragment_name");
Related
I am a java-illiterate, and still trying to develop a app for my personal use.
I have started with android-studio's "Tabbed-Activity", and mostly unaltered except a fragment and a bundle in MainActivity.
Here are my codes:
MainActivity
public class MainActivity extends AppCompatActivity {
private static final int REQUEST_PERMISSIONS_REQUEST_CODE = 34;
private static final String TAG = MainActivity.class.getSimpleName();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//FloatingActionButton fab = findViewById(R.id.fab);
Bundle bundle = new Bundle();
bundle.putDouble("loclat", 25.4358);
bundle.putDouble("loclang",81.8463);
Fragment SunFragment = new SunFragment();
SunFragment.setArguments(bundle);
setContentView(R.layout.activity_main);
SectionsPagerAdapter sectionsPagerAdapter = new SectionsPagerAdapter(this, getSupportFragmentManager());
ViewPager viewPager = findViewById(R.id.view_pager);
viewPager.setAdapter(sectionsPagerAdapter);
TabLayout tabs = findViewById(R.id.tabs);
tabs.setupWithViewPager(viewPager);
}
}
SectionsPagerAdapter
public class SectionsPagerAdapter extends FragmentPagerAdapter {
#StringRes
private static final int[] TAB_TITLES = new int[]{R.string.tab_text_1, R.string.tab_text_2, R.string.tab_text_3};
private final Context mContext;
public SectionsPagerAdapter(Context context, FragmentManager fm) {
super(fm);
mContext = context;
}
#Override
public Fragment getItem(int position) {
// getItem is called to instantiate the fragment for the given page.
// Return a PlaceholderFragment (defined as a static inner class below).
//return PlaceholderFragment.newInstance(position + 1);
switch (position) {
case 0:
return new SunFragment();
//return PlaceholderFragment.newInstance(pos + 5);
case 1:
return PlaceholderFragment.newInstance(1);
//return SecondFragment.newInstance();
//return PlaceholderFragment.newInstance(pos + 1);
default:
return PlaceholderFragment.newInstance(2);
}
}
#Nullable
#Override
public CharSequence getPageTitle(int position) {
return mContext.getResources().getString(TAB_TITLES[position]);
}
#Override
public int getCount() {
// Show 2 total pages.
return 3;
}
}
And finally, The SunFragment, where I want my bundled data from MainActivity:
public class SunFragment extends Fragment {
List<SunSession> sunsList;
Typeface sunfont;
Double Dlat;
Double Dlang;
//to be called by the MainActivity
public SunFragment() {
// Required empty public constructor
}
private static final String KEY_LOCATION_NAME = "location_name";
public String TAG ="SunFragment";
public String location;//="No location name found";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Retrieve location and camera position from saved instance state.
if (savedInstanceState != null) {
location = savedInstanceState.getCharSequence(KEY_LOCATION_NAME).toString();
System.out.println("OnCreate location "+location);
// Dlat = getArguments().getDouble("loclat");
//Dlang = getArguments().getDouble("loclang");
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.fragment_sun, container, false);
//onSaveInstanceState(new Bundle());
if (getArguments() != null) {
Dlat = getArguments().getDouble("loclat");
Dlang = getArguments().getDouble("loclang");
} else {
Dlat=23.1;
Dlang=79.9864;
}
Log.e("Lat", Double.toString(Dlat));
I have followed this blog to make it, but no value is passed. Kindly help.
NB. This is a better described, and detailed question of my earlier question, which I understand, needs more code to be shown.
In your MainActivity, your sunFragment is unused. Remove this part:
/*Bundle bundle = new Bundle();
bundle.putDouble("loclat", 25.4358);
bundle.putDouble("loclang",81.8463);
Fragment SunFragment = new SunFragment();
SunFragment.setArguments(bundle);*/
You have to set bundle to fragment inside your SectionsPagerAdapter
case 0:
Bundle bundle = new Bundle();
bundle.putDouble("loclat", 25.4358);
bundle.putDouble("loclang",81.8463);
Fragment sunFragment = new SunFragment();
sunFragment.setArguments(bundle);
return sunFragment;
But if you need to set the bundle to fragment from MainActivity. Then use a callback in that purpose.
This way you can pass data from your mainActivity to fragment
MainActivity onCreate method
adapter = new Adapter(getChildFragmentManager());
SquadsTeamListFragment teamA =
SquadsTeamListFragment.newInstance(teamAData,teamBData
adapter.addFragment(teamA, teamAName);
viewPager.setAdapter(adapter);
tabLayout.setupWithViewPager(viewPager);
use this adapter in your main activity
static class Adapter extends FragmentStatePagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
Adapter(FragmentManager manager) {
super(manager);
}
#Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
#Override
public int getCount() {
return mFragmentList.size();
}
void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
#Override
public CharSequence getPageTitle(int position){
return mFragmentTitleList.get(position);
}
}
receive data to fragment (SquadsTeamListFragment .java)
public static SquadsTeamListFragment newInstance(String playerList, String
oppPlayerList) {
SquadsTeamListFragment fragment = new SquadsTeamListFragment();
Bundle args = new Bundle();
args.putString(ARG_TEAM_DATA, playerList);
args.putString(ARG_OPP_TEAM_DATA, oppPlayerList);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
playerList = getArguments().getString(ARG_TEAM_DATA);
oppPlayerList = getArguments().getString(ARG_OPP_TEAM_DATA);
}
}
I have a main activity which shows 3 fragments inside View Pagers with tabs.
mainActivity.java
public class mainActivity extends AppCompatActivity {
globalVariableActivity variable = new globalVariableActivity();
private APIService mAPIService;
private TextView mResponseTv;
private RecyclerView recyclerView;
private Token token = new Token("","","");
private Gson gson = new Gson();
private Context context=mainActivity.this;
private Toolbar toolbar;
private TabLayout tabLayout;
private ViewPager viewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//check if token is still active
String current_token=token.getToken(context);
MyFirebaseInstanceIDService Fcm= new MyFirebaseInstanceIDService();
Fcm.onTokenRefresh(context,current_token);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
viewPager = (ViewPager) findViewById(R.id.viewpager);
setupViewPager(viewPager);
tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);
}
private void setupViewPager(ViewPager viewPager) {
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFragment(new BeritaFragment(), "Berita");
adapter.addFragment(new DiskusiFragment(), "Diskusi");
adapter.addFragment(new PesanFragment(), "Pesan");
viewPager.setAdapter(adapter);
}
class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager manager) {
super(manager);
}
#Override
public Fragment getItem(int position) {
//Toast.makeText(context,"Item " + position + " shown.", Toast.LENGTH_SHORT).show();
return mFragmentList.get(position);
}
#Override
public int getCount() {
return mFragmentList.size();
}
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
#Override
public CharSequence getPageTitle(int position) {
Toast.makeText(context,"Position : " + position + " Title : "+ mFragmentTitleList.get(position) + " shown.", Toast.LENGTH_SHORT).show();
return mFragmentTitleList.get(position);
}
}
interface LyfecycleListener {
void onCreatedView();
}
here's the first fragment code
beritaFragment.java
public class BeritaFragment extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private APIService mAPIService = APIUtils.getAPIService();;
private Gson gson = new Gson();
private TextView createdAtText;
private TextView judulText;
private ImageView imageView;
private RecyclerView mRecyclerView;
private ListAdapter mListadapter;
private ArrayList<DataBerita> list_berita= new ArrayList<>();
private OnFragmentInteractionListener mListener;
public BeritaFragment() {
}
// TODO: Rename and change types and number of parameters
public static BeritaFragment newInstance(String param1, String param2) {
BeritaFragment fragment = new BeritaFragment();
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getBeritaTask getBerita= new getBeritaTask();
try {
Log.d("berita :", "On create 1");
getBerita.execute().get(10000, TimeUnit.MILLISECONDS);
Log.d("berita :", "On create 2");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_berita, container, false);
Log.d("Berita","On create view");
Toast.makeText(getActivity() ,"Berita Fragment onCreateView", Toast.LENGTH_SHORT).show();
ArrayList<DataBerita> data_berita;
mRecyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
judulText = (TextView)view.findViewById(R.id.summary_judul);
createdAtText = (TextView)view.findViewById(R.id.created_at);
//imageView = (ImageView)view.findViewById(R.id.gambar);
final LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
layoutManager.setOrientation(LinearLayoutManager.VERTICAL);
mRecyclerView.setLayoutManager(layoutManager);
//data_berita=getBeritaList();
Log.d("Berita","1");
Log.d("Berita List : ", list_berita.toString());
Log.d("Berita","3");
mListadapter = new ListAdapter(list_berita);
mRecyclerView.setAdapter(mListadapter);
//Log.d("Berita view :", view.toString());
return view;
}
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
public class ListAdapter extends RecyclerView.Adapter<ListAdapter.ViewHolder>
{
private ArrayList<DataBerita> dataList;
public ListAdapter(ArrayList<DataBerita> data)
{
this.dataList = data;
}
public class ViewHolder extends RecyclerView.ViewHolder
{
TextView judulText;
TextView waktuText;
ImageView gambarView;
public ViewHolder(View itemView)
{
super(itemView);
this.judulText = (TextView) itemView.findViewById(R.id.summary_judul);
this.waktuText = (TextView) itemView.findViewById(R.id.created_at);
//this.gambarView = (ImageView) itemView.findViewById(R.id.gambar);
}
}
#Override
public ListAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.berita_list_layout, parent, false);
ViewHolder viewHolder = new ViewHolder(view);
return viewHolder;
}
#Override
public void onBindViewHolder(ListAdapter.ViewHolder holder, final int position)
{
Uri ImageURI=Uri.parse(dataList.get(position).getGambar_utama());
holder.judulText.setText(dataList.get(position).getSummary_judul());
holder.waktuText.setText(dataList.get(position).getCreated_at());
//holder.gambarView.setImageURI(ImageURI);
holder.itemView.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
Toast.makeText(getActivity(), "Item " + position + " is clicked.", Toast.LENGTH_SHORT).show();
}
});
}
#Override
public int getItemCount()
{
return dataList.size();
}
}
private class getBeritaTask extends AsyncTask<Void, Void, Void> {
protected void onPreExecute() {
Log.d("Berita","2.1");
}
protected Void doInBackground(Void... voids) {
mAPIService.getBeritaList().enqueue(new Callback<Berita>() {
#Override
public void onResponse(Call<Berita> call, Response<Berita> response) {
list_berita = new ArrayList<>();
DataBerita data_berita = new DataBerita("","","","");
String id_berita;
String judul;
String gambar_utama;
String created_at;
Log.d("Berita","2.2");
if(response.isSuccessful()) {
Berita body = gson.fromJson(response.body().toString(),Berita.class);
for (int i = 0; i < body.getList_berita().getData().size(); i ++) {
id_berita=body.getList_berita().getData().get(i).getId_berita();
judul=body.getList_berita().getData().get(i).getSummary_judul();
gambar_utama=body.getList_berita().getData().get(i).getGambar_utama();
created_at=body.getList_berita().getData().get(i).getCreated_at();
data_berita = new DataBerita(id_berita,judul,gambar_utama,created_at);
list_berita.add(data_berita);
}
Log.d("Berita List",list_berita.toString());
}else{
Log.d("Berita", "Fail");
}
}
#Override
public void onFailure(Call<Berita> call, Throwable t) {
Log.d("Berita Fail", t.getMessage());
}
});
return null;
}
}
here's the 2nd and 3rd fragment (these 2 fragments are still mostly empty, with code for toast and log only for now)
DiskusiFragment.java
public class DiskusiFragment extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
private OnFragmentInteractionListener mListener;
public DiskusiFragment() {
// Required empty public constructor
}
// TODO: Rename and change types and number of parameters
public static DiskusiFragment newInstance(String param1, String param2) {
DiskusiFragment fragment = new DiskusiFragment();
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Toast.makeText(getActivity() ,"Diskusi Fragment onCreateView", Toast.LENGTH_SHORT).show();
return inflater.inflate(R.layout.fragment_diskusi, container, false);
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
}
here's the problem,
fragment onCreateView function seems to be called on / in the wrong fragment.
when I start the app here's what happened :
Item position 0 , 1, and 2 is called
1st fragment on create view is called, and 2nd fragment on create view is called immediately
what happens next, depends on what I do :
when I change from 1st fragment => 2nd fragment, 3rd fragment on create view is called
when I change from 1st fragment => 3rd fragment, 3rd fragment on create view is called
when I switch from 2nd fragment => 1st fragment, no fragment on create view called
when I switch from 2nd fragment => 3rd fragment, no fragment on create view called
when I switch from 3rd fragment => 2nd fragment, no fragment on create view called (or sometimes 1st fragment on create view is called)
when I change from 3rd fragment => 1st fragment, 1st fragment on create view called
is this what suppose (in regard to onCreateView function is called on the wrong fragment) to happen?
if not, where did I code wrong?
Thank you very much
*EDIT : this behaviour is normal, I'm really new to android. Very sorry for the inconvenience guys
The FragmentPagerAdapter keeps additional fragments, besides the one shown, in the resumed state.
If you want to initialize stuff in the fragment you should do it when
OnCreate is called.
Anything that is related to the UI been loaded properly should happen on
onViewCreated
In addition, if you want to receive more information about how to handle fragments inside a ViewPager
#Shreyas Shetty answered it really well on this thread
What do you mean by "wrong" fragment? View pager creates next fragment prior to navigating to it to make the transition smooth and quick. And when the fragment is created its lifecycle methods are called accordingly, there's nothing wrong with this behaviour. If you want to perform some action when the user swipes to specific fragment in your view pager, you can use OnPageChangeListener.
I need some help with the logic to my problem. I have searched already on here for posts discussing similar issues, however haven't yet had success in fixing my problem so I don't wish to make this a duplicate post.
I am working on an app and I am having issues in displaying parsed JSON Data in a recycler view within a Slide Tab Fragment. I have a Sliding Tabs on my main activity with five fragments in total, one for each tab (5 tabs in total). What I want to do for the third tab is to display a recycler view with parsed JSON data that is being retrieved from the server. I have the same functionality within an activity for my other recyclerviews and they work fine. I was just struggling slightly on how to achieve this inside a fragment. I am providing the below code for troubleshooting and debugging purposes:
Here is the code to my MainActivity.java
public class MainActivity extends BaseActivity {
private ViewPager mPager;
private SlidingTabLayout mTabs;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// To track statistics around application
ParseAnalytics.trackAppOpened(getIntent());
// inform the Parse Cloud that it is ready for notifications
ParseInstallation.getCurrentInstallation().saveInBackground();
//Calling Activate Toolbar method
activateToolBar();
mPager = (ViewPager) findViewById(R.id.pager);
//Setting the Adapter on the view pager first. Passing the fragment manager through as an argument
mPager.setAdapter(new MyPagerAdapter(getSupportFragmentManager()));
mTabs = (SlidingTabLayout) findViewById(R.id.tabs);
//Setting the custom Tab View as the Sliding Tabs Layout
mTabs.setCustomTabView(R.layout.custom_tab_view, R.id.tabText);
mTabs.setDistributeEvenly(true);
//mTabs.setSelectedIndicatorColors(getResources().getColor(R.color.tabIndicatorColour));
mTabs.setBackgroundColor(getResources().getColor(R.color.basePrimaryBackgroundColour));
//Setting the ViewPager as the tabs
mTabs.setViewPager(mPager);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
//getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
//int id = item.getItemId();
//noinspection SimplifiableIfStatement
//if (id == R.id.action_settings) {
// return true;
//}
return super.onOptionsItemSelected(item);
}
class MyPagerAdapter extends FragmentPagerAdapter {
String[] tabs;
public MyPagerAdapter(FragmentManager fm) {
super(fm);
//Initialising the strings array of the tabs
tabs = getResources().getStringArray(R.array.tabs);
}
/*
//Setting up integer array of icons
int icons[] = {R.drawable.about_us, R.drawable.campus, R.drawable.events, R.drawable.learning, R.drawable.sewa};
//Defined from strings.xml
String[] tabText = getResources().getStringArray(R.array.tabs);
public MyPagerAdapter(FragmentManager fm) {
super(fm);
//Initialising the strings array of tabs
tabText = getResources().getStringArray(R.array.tabs);
}
*/
#Override
public Fragment getItem(int position) {
if (position == 0) // if the position is 0 we are returning the First tab
{
Tab1 tab1 = new Tab1();
return tab1;
} else if (position == 1)
{
Tab2 tab2 = new Tab2();
return tab2;
} else if (position == 2)
{
Tab3 tab3 = new Tab3();
return tab3;
} else if (position == 3)
{
Tab4 tab4 = new Tab4();
return tab4;
} else
{
Tab5 tab5 = new Tab5();
return tab5;
}
}
#Override
public CharSequence getPageTitle(int position) {
//Return the text of the position clicked and display this as the title for the tab
return tabs[position];
}
#Override
public int getCount() {
return 5;
}
}
}
This is the code for my RecyclerViewAdapterEvents.java
public class RecyclerViewAdapterEvents extends RecyclerView.Adapter<RecyclerViewAdapterEvents.MyViewHolder> {
private LayoutInflater inflater;
//private EventsActivity activity;
private List<JSONEventsItem> data = Collections.emptyList();
private Context mContext;
//Variable for the on click Listener
private ClickListener clickListener;
//Passing in the array list argument
public RecyclerViewAdapterEvents(Context context, List<JSONEventsItem> data) {
this.mContext = context;
//this.activity = activity;
inflater = LayoutInflater.from(context);
//Setting the array list data to the argument passed in
this.data = data;
}
#Override
public RecyclerViewAdapterEvents.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
//Inflating the row and getting the root of view of the custom row (Linear Layout)
View view = inflater.inflate(R.layout.custom_row, parent, false);
//Passing the root view through as an argument
MyViewHolder holder = new MyViewHolder(view);
//Returning the view holder
return holder;
}
#Override
public void onBindViewHolder(RecyclerViewAdapterEvents.MyViewHolder holder, int position) {
//This will get the current position of the JSONEventItem object from the array
JSONEventsItem eventsItem = data.get(position);
//Setting the event name to the name of the event retrieved from the Database (converting from JSON)
holder.eventName.setText(Html.fromHtml(eventsItem.getEventName()));
}
#Override
public int getItemCount() {
return (null != data ? data.size() : 0);
}
public void setClickListener(ClickListener clicklistener) {
this.clickListener = clicklistener;
}
public interface ClickListener {
}
class MyViewHolder extends RecyclerView.ViewHolder {
TextView eventName;
public MyViewHolder(View itemView) {
super(itemView);
//Here setting the id of the textview in the recycler view holder to be the list view from the custom_row xml
eventName = (TextView) itemView.
findViewById(R.id.listText);
}
}
}
Here is the class file for Tab3 Fragment, Tab3.java
public class Tab3 extends Fragment implements RecyclerViewAdapterEvents.ClickListener{
private RecyclerView mRecyclerView;
//Creating an instance of the adapter object
private RecyclerViewAdapterEvents adapter;
private List<JSONEventsItem> EventsList;
private String jsonString = "";
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View v = inflater.inflate(R.layout.tab_3,container,false);
//Instantiating the recycler view as defined in tab_1
mRecyclerView = (RecyclerView) v.findViewById(R.id.about_us_recycler_view);
//Adding item decoration. Recycler view divider
mRecyclerView.addItemDecoration(new DividerItemDecoration(getActivity(), DividerItemDecoration.VERTICAL_LIST));
//Initialising the adapter - Passing in the activity and the getData method
adapter = new RecyclerViewAdapterEvents(getActivity(), EventsList);
//Here passing in the click listener into the Adapter. 'this' signifies that it is the fragment that handles the click listener.
//This is possible as the on Click Listener interface is being implemented.
adapter.setClickListener(this);
//Setting the adapter
mRecyclerView.setAdapter(adapter);
//Setting the Layout
mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
//Downloading data from below url (Universal Resource Locator) to obtain data from the Admin database
final String url = "http://dbchudasama.webfactional.com/jsonscript.php";
new AsyncHTTPTask().execute(url);
return v;
}
public class AsyncHTTPTask extends AsyncTask<String, Void, Integer> {
#Override
protected Integer doInBackground(String... params) {
Integer result = 0;
HttpURLConnection urlConnection;
try {
URL url = new URL(params[0]);
urlConnection = (HttpURLConnection) url.openConnection();
int statusCode = urlConnection.getResponseCode();
// 200 represents HTTP OK
if (statusCode == 200) {
BufferedReader r = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
StringBuilder response = new StringBuilder();
String line;
while ((line = r.readLine()) != null) {
response.append(line);
}
jsonString = response.toString();
parseResult();
result = 1; // Successful
} else {
result = 0; //"Failed to fetch data!";
}
} catch (Exception e) {
Log.d("Exception Caught", e.getLocalizedMessage());
}
return result; //"Failed to fetch data!";
}
#Override
protected void onPostExecute(Integer result) {
super.onPostExecute(result);
//adapter.getItemCount();
if (result == 1) {
//Intent intent = getIntent();
//intent.getSerializableExtra("JSON Admin");
//Initialising the adapter - Passing in the activity and the parsed Admin Team List
adapter = new RecyclerViewAdapterEvents(getActivity(), EventsList);
//Setting the adapter
mRecyclerView.setAdapter(adapter);
} else {
Toast.makeText(getActivity(), "Failed to fetch data!", Toast.LENGTH_SHORT).show();
}
}
}
//This method will parse the RAW data downloaded from the server
private void parseResult() {
try {
JSONArray AdminArrays = new JSONArray(jsonString);
EventsList = new ArrayList<>();
for (int i = 0; i < AdminArrays.length(); i++) {
JSONObject AdminArrayObject = AdminArrays.getJSONObject(i);
JSONEventsItem item = new JSONEventsItem();
item.setEventName(AdminArrayObject.getString("eventName"));
this.EventsList.add(item);
Log.e("Event Name", AdminArrayObject.getString("eventName"));
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
The Tab3.java code has crashed all my other tabs and is giving a null pointer exception on the the getActivity() method, as this is being performed on a null object reference. Could I just declare an activity of type EventsActivity and pass this through instead? Also So I am slightly unsure how to resolve this. For completeness I have also written the same code within an activity EventsActivity.java which I know will work. It is just getting it to run within the fragment.
public class EventsActivity extends BaseActivity implements RecyclerViewAdapterEvents.ClickListener {
private RecyclerView mRecyclerView;
//Creating an instance of the adapter object
private RecyclerViewAdapterEvents adapter;
private List<JSONEventsItem> EventsList;
private EventsActivity activity;
private String jsonString = "";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.tab_3);
//Calling Activate Toolbar method (with the Back button enabled)
activateToolbarWithHomeEnabled();
//Instantiating the recycler view as defined in admin_team
//mRecyclerView = (RecyclerView) findViewById(R.id.events_recycler_view);
//Adding item decoration. Recycler view divider
mRecyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL_LIST));
//Initialising the adapter - Passing in the activity and the parsed Events List
adapter = new RecyclerViewAdapterEvents(this, EventsList);
//Setting the adapter
mRecyclerView.setAdapter(adapter);
//Setting the Layout
//mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
//Downloading data from below url (Universal Resource Locator) to obtain data from the Admin database
final String url = "http://dbchudasama.webfactional.com/jsonscript.php";
new AsyncHTTPTask().execute(url);
}
public class AsyncHTTPTask extends AsyncTask<String, Void, Integer> {
#Override
protected Integer doInBackground(String... params) {
Integer result = 0;
HttpURLConnection urlConnection;
try {
URL url = new URL(params[0]);
urlConnection = (HttpURLConnection) url.openConnection();
int statusCode = urlConnection.getResponseCode();
// 200 represents HTTP OK
if (statusCode == 200) {
BufferedReader r = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
StringBuilder response = new StringBuilder();
String line;
while ((line = r.readLine()) != null) {
response.append(line);
}
jsonString = response.toString();
parseResult();
result = 1; // Successful
} else {
result = 0; //"Failed to fetch data!";
}
} catch (Exception e) {
Log.d("Exception Caught", e.getLocalizedMessage());
}
return result; //"Failed to fetch data!";
}
#Override
protected void onPostExecute(Integer result) {
super.onPostExecute(result);
//adapter.getItemCount();
if (result == 1) {
//Intent intent = getIntent();
//intent.getSerializableExtra("JSON Admin");
//Initialising the adapter - Passing in the activity and the parsed Admin Team List
adapter = new RecyclerViewAdapterEvents(EventsActivity.this, EventsList);
//Setting the adapter
mRecyclerView.setAdapter(adapter);
} else {
Toast.makeText(EventsActivity.this, "Failed to fetch data!", Toast.LENGTH_SHORT).show();
}
}
}
//This method will parse the RAW data downloaded from the server
private void parseResult() {
try {
JSONArray AdminArrays = new JSONArray(jsonString);
EventsList = new ArrayList<>();
for (int i = 0; i < AdminArrays.length(); i++) {
JSONObject AdminArrayObject = AdminArrays.getJSONObject(i);
JSONEventsItem item = new JSONEventsItem();
item.setEventName(AdminArrayObject.getString("eventName"));
this.EventsList.add(item);
Log.e("Event Name", AdminArrayObject.getString("eventName"));
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
Here is my crash log from Logcat:
11-09 18:56:21.587 2961-2961/com.divyeshbc.NHSF E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.divyeshbc.NHSF, PID: 2961
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.widget.RecyclerView.addItemDecoration(android.support.v7.widget.RecyclerView$ItemDecoration)' on a null object reference
at com.divyeshbc.NHSF.tabs.events.Tab3.onCreateView(Tab3.java:53)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:1789)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:955)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1138)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:740)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1501)
at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:490)
at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:141)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1105)
at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:551)
at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:513)
at android.support.v4.view.ViewPager.setCurrentItem(ViewPager.java:494)
at com.divyeshbc.NHSF.tabs.SlidingTabLayout$TabClickListener.onClick(SlidingTabLayout.java:324)
at android.view.View.performClick(View.java:4756)
at android.view.View$PerformClick.run(View.java:19749)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
Where am I going wrong? Any guidance will be highly helpful :).
Thanks
i'm having some issues implementing a Sliding Tabs activity that contains 2 Fragments and a Swipe Down to Refresh layout, namely implementing the Swipe Down to Refresh part (the rest is working just fine).
First here are my XML files.
The Main Activity XML , which contains the ViewPager wrapped in an SwipeRefreshLayout :
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.popal.soul.MovieListActivityTEST">
<com.example.popal.soul.SlidingTabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:elevation="2dp"
android:background="#color/ColorPrimary"/>
<android.support.v4.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/swipeContainer"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:layout_weight="1">
</android.support.v4.view.ViewPager>
</android.support.v4.widget.SwipeRefreshLayout>
And the first tab XML , one of the 2 tabs (both are similar, so i`ll only post one)
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android">
<android.support.v7.widget.RecyclerView
android:id="#+id/cardList"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<ProgressBar
android:id="#+id/progress_bar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true" />
</RelativeLayout>
Now, my main activity, which handles the ViewPager, Adapter an the SlidingTabsLayout.
public class MovieListActivityTEST extends AppCompatActivity {
ViewPager pager;
ViewPagerAdapter adapter;
SlidingTabLayout tabs;
CharSequence Titles[]={"Home","Events"};
int Numboftabs =2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_movie_list_activity_test);
// Creating The ViewPagerAdapter and Passing Fragment Manager, Titles fot the Tabs and Number Of Tabs.
adapter = new ViewPagerAdapter(getSupportFragmentManager(),Titles,Numboftabs);
// Assigning ViewPager View and setting the adapter
pager = (ViewPager) findViewById(R.id.pager);
pager.setAdapter(adapter);
// Assiging the Sliding Tab Layout View
tabs = (SlidingTabLayout) findViewById(R.id.tabs);
tabs.setDistributeEvenly(true);
// Setting Custom Color for the Scroll bar indicator of the Tab View
tabs.setCustomTabColorizer(new SlidingTabLayout.TabColorizer() {
#Override
public int getIndicatorColor(int position) {
return getResources().getColor(R.color.tabsScrollColor);
}
});
// Setting the ViewPager For the SlidingTabsLayout
tabs.setViewPager(pager);
}
And finally, my fragment for the first Tab
public class Tab1 extends Fragment {
public MovieListAdapter movieListAdaptor;
public RecyclerView recycleList;
private SwipeRefreshLayout swipeContainer;
private List<MovieListAdapter.MovieDetails> movieList = new ArrayList<MovieListAdapter.MovieDetails>();
private ProgressBar progressBar;
private final static String MOVIES_POST_REQUEST ="//Long String, Edited out since it`s not relevant"
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v =inflater.inflate(R.layout.tab_1, container, false);
recycleList = (RecyclerView) v.findViewById(R.id.cardList);
progressBar = (ProgressBar) v.findViewById(R.id.progress_bar);
progressBar.setVisibility(View.VISIBLE);
swipeContainer = (SwipeRefreshLayout) v.findViewById(R.id.swipeContainer);
LinearLayoutManager llm = new LinearLayoutManager(getActivity());
llm.setOrientation(LinearLayoutManager.VERTICAL);
recycleList.setLayoutManager(llm);
swipeContainer.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
movieListAdaptor.clear();
new Send_data_to_server().execute(MOVIES_POST_REQUEST);
swipeContainer.setRefreshing(false);
}
});
new Send_data_to_server().execute(MOVIES_POST_REQUEST);
return v;
}
The issue is, i'm getting a NULL Pointer Exception at swipeContainer.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {...} method, which i guess is because the Swipe-to-Refresh layout is in the main activity XML, and not the tabs fragment. So what is the proper way to implement this ? I also tried implementing a Swipe to refresh layout in one of the Tabs XML instead of wrapping the ViewPager in it, like above, but it would crash when swiping from tab to another.
Here`s the code from the entire fragment in Tab1, for tobs answer below
public class MoviesTabFragment extends Fragment implements Refreshable {
public MovieListAdapter movieListAdaptor;
public RecyclerView recycleList;
//private SwipeRefreshLayout swipeContainer;
public List<MovieListAdapter.MovieDetails> movieList = new ArrayList<MovieListAdapter.MovieDetails>();
public ProgressBar progressBar;
public final static String MOVIES_POST_REQUEST ="";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v =inflater.inflate(R.layout.tab_1, container, false);
recycleList = (RecyclerView) v.findViewById(R.id.cardList);
progressBar = (ProgressBar) v.findViewById(R.id.progress_bar);
LinearLayoutManager llm = new LinearLayoutManager(getActivity());
llm.setOrientation(LinearLayoutManager.VERTICAL);
recycleList.setLayoutManager(llm);
new Send_data_to_server().execute(MOVIES_POST_REQUEST);
return v;
}
#Override
public void refresh() {
new Send_data_to_server().execute(MOVIES_POST_REQUEST);
}
public class Send_data_to_server extends AsyncTask<String, Void, String> {
private String data_poster;
private String data_fanart;
// protected void onPreExecute() {
// progressBar.setVisibility(View.VISIBLE);
// }
protected String doInBackground(String... params)
{
String jason_data = params[0];
HttpClient http_con = new HttpClient();
String output_from_server = http_con.establish_con(jason_data);
Log.i("DataFromServer", output_from_server);
JSONObject json_Obj = null;
JSONObject child_obj = null; //creating the "result" object in the main JSON Object
try {
json_Obj = new JSONObject(output_from_server);
child_obj = create_subObject("result", json_Obj);
JSONArray jsonArray = child_obj.optJSONArray("movies");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
String title_data = jsonObject.optString("label").toString();
String plot_data = jsonObject.optString("plot").toString();
String year_data = jsonObject.optString("year").toString();
String movie_id_data = jsonObject.optString("movieid").toString();
String imdb_score = jsonObject.optString("rating").toString();
String imdb_score_short = imdb_score.substring(0, 3);
JSONObject child_obj2 = create_subObject("art", jsonObject);
data_poster = child_obj2.optString("poster").toString();
data_fanart = child_obj2.optString("fanart").toString();
JSONEncodePosterFanart encodePosterFanart = new JSONEncodePosterFanart();
String jason_dataPoster = encodePosterFanart.GetPosterFanartEncodedURL(data_poster);
String jason_dataFanart = encodePosterFanart.GetPosterFanartEncodedURL(data_fanart);
HttpClient http = new HttpClient();
String output_from_serverPoster = http.establish_con(jason_dataPoster);
HttpClient http2 = new HttpClient();
String output_from_serverFanart = http2.establish_con(jason_dataFanart);
JSONPosterFanart poster_fanart = new JSONPosterFanart();
String post_dl = poster_fanart.GetPosterFanart(output_from_serverPoster);
JSONPosterFanart poster_fanart2 = new JSONPosterFanart();
String fanart_dl = poster_fanart2.GetPosterFanart(output_from_serverFanart);
if (null == movieList) {
movieList = new ArrayList<MovieListAdapter.MovieDetails>();
}
MovieListAdapter.MovieDetails item = new MovieListAdapter.MovieDetails(title_data+" ("+year_data+")", post_dl, fanart_dl,plot_data,movie_id_data,imdb_score_short);
movieList.add(item);
}
} catch (JSONException e) {
e.printStackTrace();
}
return output_from_server;
}
protected void onPostExecute(String output_from_server) {
super.onPostExecute(output_from_server);
//progressBar.setVisibility(View.INVISIBLE);
movieListAdaptor = new MovieListAdapter(getActivity(), movieList);
recycleList.setAdapter(movieListAdaptor);
}
private JSONObject create_subObject(String tagName, JSONObject jObj) throws JSONException {
JSONObject subObj = jObj.getJSONObject(tagName); //getJSONObject returns the value from tagName (in our case jason_Obj that is being passed ar a param)
return subObj;
}
}
}
And the RecycleView adapter:
public class MovieListAdapter extends RecyclerView.Adapter<MovieListAdapter.MovieViewHolder> {
public List<MovieDetails> movieList;
private Context mContext;
public MovieListAdapter(Context mContext, List<MovieDetails> movieList) {
this.mContext = mContext;
this.movieList = movieList;
}
#Override
public int getItemCount() {
return movieList.size();
}
public void clear() {
movieList.clear();
notifyDataSetChanged();
}
#Override
public MovieViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View itemView = LayoutInflater.
from(viewGroup.getContext()).
inflate(R.layout.card_layout_movies_list, viewGroup, false);
return new MovieViewHolder(itemView);
}
#Override
public void onBindViewHolder(MovieViewHolder movieViewHolder, int i) {
MovieDetails mdet = movieList.get(i);
String fanart = "http://192.168.1.128/"+mdet.getImageViewFanart();
String poster = "http://192.168.1.128/"+mdet.getImageViewPoster();
Log.i("fanart", fanart);
Log.i("poster", poster);
movieViewHolder.vTitle.setText(mdet.Title);
Picasso.with(mContext).load(poster)
.resize(500, 746)
.error(R.drawable.poster_placeholder)
.placeholder(R.drawable.poster_placeholder)
.into(movieViewHolder.vPoster);
Picasso.with(mContext).load(fanart)
.resize(960, 540)
.error(R.drawable.fanart_placeholder)
.placeholder(R.drawable.fanart_placeholder)
.into(movieViewHolder.vFanart);
movieViewHolder.vplot = mdet.getPlot();
movieViewHolder.vmovie_id = mdet.getMovie_id();
}
public class MovieViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
protected TextView vTitle;
protected ImageView vPoster;
protected ImageView vFanart;
protected String vplot;
protected String vmovie_id;
protected String vimdb_score;
public MovieViewHolder(View v)
{
super(v);
vplot = new String();
vmovie_id = new String();
vimdb_score = new String();
vTitle = (TextView) v.findViewById(R.id.title);
vPoster = (ImageView) v.findViewById(R.id.imageViewPoster);
vFanart = (ImageView) v.findViewById(R.id.imageViewFanart);
v.setOnClickListener(this);
}
#Override
public void onClick(View v) {
int position = getLayoutPosition();
MovieDetails mov = movieList.get(position);
Intent intent = new Intent(mContext, MovieDetailsPageActivity.class);
Bundle bundle = new Bundle();
bundle.putString("movieid", mov.getMovie_id());
bundle.putString("plot", vplot);
bundle.putString("fanart_path", mov.getImageViewFanart());
bundle.putString("imdb_score", mov.getImdb_score());
intent.putExtras(bundle);
mContext.startActivity(intent);
}
}
public static class MovieDetails {
protected String Title;
protected String imageViewPoster;
protected String imageViewFanart;
protected String plot;
protected String movie_id;
protected String imdb_score;
public MovieDetails(String Title, String imageViewPoster,String imageViewFanart, String plot, String movie_id ,String imdb_score)
{
this.Title = Title;
this.imageViewPoster = imageViewPoster;
this.imageViewFanart = imageViewFanart;
this.plot = plot;
this.movie_id = movie_id;
this.imdb_score = imdb_score;
}
public String getTitle() {return Title;}
public String getImageViewPoster() {
return imageViewPoster;
}
public String getImageViewFanart() {
return imageViewFanart;
}
public String getPlot() {return plot;}
public String getMovie_id() {return movie_id;}
public String getImdb_score() {return imdb_score;}
}
}
public class ViewPagerAdapter extends FragmentStatePagerAdapter {
CharSequence Titles[];
int NumbOfTabs;
public ViewPagerAdapter(FragmentManager fm,CharSequence mTitles[], int mNumbOfTabsumb) {
super(fm);
this.Titles = mTitles;
this.NumbOfTabs = mNumbOfTabsumb;
}
#Override
public Fragment getItem(int position) {
if(position == 0)
{
MoviesTabFragment moviesTabFragment = new MoviesTabFragment();
return moviesTabFragment;
}
else
{
TVShowsTabFragment TVShowsTabFragment = new TVShowsTabFragment();
return TVShowsTabFragment;
}
}
#Override
public CharSequence getPageTitle(int position) {
return Titles[position];
}
#Override
public int getCount() {
return NumbOfTabs;
}
You're getting the NullPointerException because you inflate your fragment layout from R.layout.tab_1 which does not contain a SwipeRefreshLayout.
If you want the layout to be the parent of your ViewPager, I would recommend you to move your code which manages the RefreshLayout to the MainActivity:
public class MovieListActivityTEST extends AppCompatActivity {
ViewPager pager;
ViewPagerAdapter adapter;
SwipeRefreshLayout refreshLayout;
SlidingTabLayout tabs;
CharSequence Titles[]={"Home","Events"};
int Numboftabs =2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_movie_list_activity_test);
// Creating The ViewPagerAdapter and Passing Fragment Manager, Titles fot the Tabs and Number Of Tabs.
adapter = new ViewPagerAdapter(getSupportFragmentManager(),Titles,Numboftabs);
// Assigning ViewPager View and setting the adapter
pager = (ViewPager) findViewById(R.id.pager);
pager.setAdapter(adapter);
// Assiging the Sliding Tab Layout View
tabs = (SlidingTabLayout) findViewById(R.id.tabs);
tabs.setDistributeEvenly(true);
// Setting Custom Color for the Scroll bar indicator of the Tab View
tabs.setCustomTabColorizer(new SlidingTabLayout.TabColorizer() {
#Override
public int getIndicatorColor(int position) {
return getResources().getColor(R.color.tabsScrollColor);
}
});
// Setting the ViewPager For the SlidingTabsLayout
tabs.setViewPager(pager);
// Assign your refresh layout
refreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipeContainer);
refreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
Refreshable r = (Refreshable) adapter.getItemAt(pager.getCurrentItem());
r.refresh();
}
});
}
where each of your tab fragments implements a Refreshable interface:
public interface Refreshable {
void refresh();
}
and your adapter keeps track on all fragments:
public class ViewPagerAdapter extends FragmentStatePagerAdapter {
// list that keeps references to all attached Fragments
private SparseArray<Fragment> pages = new SparseArray<>();
...
public Fragment getItem(int position) {
Fragment f;
if(position == 0) {
...
} else { ... }
// add fragment to the list
pages.put(position, f);
}
public void destroyItem(ViewGroup container, int position, Object object) {
// remove fragment from list if it existed
if(pages.indexOfKey(position) >= 0) {
pages.remove(position);
}
super.destroyItem(container, position, object);
}
// return the attached Fragment that is associated with the given position
public Fragment getItemAt(int position) {
return pages.get(position);
}
}
This tutorial refers to the communicating between fragments but doesn't do it for tabs. I want to send data between from my "Daycare" fragment which is a tab to my "You" fragment which is also a tab. I've been stuck for a week on this. I don't really know how to combine the concept of interfaces with android tabbed fragments and data from asynctasks.
I have created an interface in my Daycare fragment. I want to send the String "daycarename" to the "you" fragment with the help of the "passparam" method. From what I understood it needs to somehow pass through the MainActivity which implements my TabClickedListener interface. How do I pass it from the MainActivity back to the other fragment?
public class MainActivity extends Activity implements ActionBar.TabListener, DaycareFragment.TabClickedListener {
SectionsPagerAdapter mSectionsPagerAdapter;
ViewPager mViewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
mSectionsPagerAdapter = new SectionsPagerAdapter(getFragmentManager(), this);
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
actionBar.setSelectedNavigationItem(position);
}
});
for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {
actionBar.addTab(
actionBar.newTab()
.setText(mSectionsPagerAdapter.getPageTitle(i))
.setTabListener(this));
}
}
#Override
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
mViewPager.setCurrentItem(tab.getPosition());
}
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return new YouFragment();
case 1:
return new DaycareFragment();
case 2:
return new ThirdFragment();
}
return null;
}
#Override
public int getCount() {
// Show 3 total pages.
return 3;
}
#Override
public CharSequence getPageTitle(int position) {
Locale l = Locale.getDefault();
switch (position) {
case 0:
return getString(R.string.title_section3).toUpperCase(l);
case 1:
return getString(R.string.title_section1).toUpperCase(l);
case 2:
return getString(R.string.title_section2).toUpperCase(l);
}
return null;
}
}
public class MainFragment extends Fragment {
private static final String ARG_SECTION_TYPE = "section type";
public MainFragment(){}
public MainFragment(int sectionNumber) {
Bundle args = new Bundle();
args.putInt(ARG_SECTION_TYPE, sectionNumber);
setArguments(args);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
//setup the view
switch(getArguments().getInt(ARG_SECTION_TYPE)) {
//hide or show fields based on page number.
}
return rootView;
}
}
#Override
public void passParam(String var) {
Toast.makeText(this, "Clicked " + var, Toast.LENGTH_LONG).show();
}
}
I am implementing an interface in my ListFragment:
public class DaycareFragment extends ListFragment {
TabClickedListener listener;
public interface TabClickedListener {
public void passParam(String var);
}
String email;
UserFunctions userFunctions;
Boolean owner;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_daycare, container, false);
movies = new ArrayList<HashMap<String, String>>();
userFunctions = new UserFunctions();
HashMap map = new HashMap();
map = userFunctions.getdauser(getActivity());
email = (String) map.get("email");
new GetDaDaycares().execute();
return rootView;
}
class GetDaDaycares extends AsyncTask<String, String, String>{
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(String... args) {
String city = "london";
try {
List<NameValuePair> params = new ArrayList<NameValuePair> ();
params.add(new BasicNameValuePair("city", city));
#SuppressWarnings("unused")
JSONObject json = parser.makeHttpRequest(getdaycare, params);
jArray = json.getJSONArray("lTable");
for (int i =0; i<jArray.length();i++){
JSONObject c = jArray.getJSONObject(i);
String daycarename = c.getString("daycarename");
HashMap<String, String> map = new HashMap<String, String>();
map.put("daycarename", daycarename);
movies.add(map);
}
} catch(JSONException e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(String zoom){
pDialog.dismiss();
getActivity().runOnUiThread(new Runnable() {
public void run() {
ListAdapter adapter = new SimpleAdapter(getActivity(), movies,
R.layout.list, new String[] {"daycarename"},
new int[]{R.id.textView1});
setListAdapter(adapter);
ListView lv = getListView();
lv.setOnItemClickListener(new OnItemClickListener(){
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
String daycarename =movies.get(position).get("daycarename");
}
});
}
});
}
}
}
If this was my problem (which it has been) I would have a central object that is in charge of 'sharing' data between the fragments.
The implementation usually seems to follow 1 of 2 paths: One, create a singleton that any object can get an instance of, or two, the activity initializes the single instance of an object and passes it to each fragment upon their initialization.
Fragments (or an AsyncTask) would then update and pull data from that central object via the Observer Pattern or on display, however you'd want.
p.s.
If you are going to have an AsyncTask in a fragment, you will want to implement a strategy for insuring your UI is not dead when it finishes. Otherwise you can throw an exception.
p.p.s
onPostExecute runs on the UI thread by default.
In your Activity:
public void passStrToYou(String daycarename)
{
FragmentManager fm = getFragmentManager();
Fragment youFrag = (YouFragment)fm.FragmentManager fm.findFragmentById(R.id.youFragment);
//call mathod 'setDayCareName' in 'you' fragment
youFrag.setDayCareName(daycarename);
}
Hope this help!