Get Fragment from ViewPager Android - android-fragments

In my MainActivity I have Transaction my MainFragment.
MainFragment mainFragment = new MainFragment();
getSupportFragmentManager().beginTransaction()
.replace(R.id.fragment_holder, mainFragment)
.addToBackStack(mainFragment.getClass().getName())
.commit();
at my MainFragment I'm using a ViewPager together with a FragmentStatePagerAdapter to host My fragment.
public class TaskPagerAdapter extends FragmentStatePagerAdapter {
private String cookieString = null;
private String userString = null;
public TaskPagerAdapter(FragmentManager fm, Cookie cookie) {
super(fm);
this.cookieString = HttpUtil.serializeCookie(cookie);
}
#Override
public Fragment getItem(int position) {
Fragment fragment = null;
switch (position) {
case 0:
fragment = new NotificationFragment();
break;
// case 1:
// break;
// case 2:
// break;
// case 3:
// break;
// case 4:
// break;
}
return fragment;
}
#Override
public int getCount() {
return 1;
}
#Override
public CharSequence getPageTitle(int position) {
return new String[]{"رویدادها", "توضیحات", "فرم ها"}[position];
}
#Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
}
and in my MainFragment:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
ButterKnife.bind(this, rootView);
mPagerAdapter = new TaskPagerAdapter(getFragmentManager(),cookie);
mViewPager.setAdapter(mPagerAdapter);
mViewPager.setCurrentItem(0);
return rootView;
according this link I write this commend into main fragment:
mViewPager.setCurrentItem(0);
Fragment page = getActivity().getSupportFragmentManager().findFragmentByTag("android:switcher:" +
R.id.pager + ":" + mViewPager.getCurrentItem());
NotificationFragment fragment = (NotificationFragment) page;
fragment.setNotificationCallBack(this);
mCountNotifyTask.getCountNotifyTask();
return rootView;
but page retrieve null!! what is you suggestion?
I am using this tutorial
I still got null.
NotificationFragment fragment = (NotificationFragment) mPagerAdapter.getRegisteredFragment(0);

Instead of using activities fragment manager, use ChildFragmentManager in your MainFragment
mPagerAdapter = new TaskPagerAdapter(getChildFragmentManager(),cookie);
mViewPager.setAdapter(mPagerAdapter);
mViewPager.setCurrentItem(0);
And to get the fragment use the child fragment manager
Fragment page = getChildFragmentManager().findFragmentByTag("android:switcher:" +
R.id.pager + ":" + mViewPager.getCurrentItem());
NotificationFragment fragment = (NotificationFragment) page;
Remember: ViewPager adds and removes fragment based on its current position
I would suggest to keep all the fragment instance in the adapter as an ArrayList and retrive them when you need it based on the position index

Related

Xamarin android. The name 'assets' does not exist in the current context

In my app I am using a fragment and inside the fragment I am trying to use
view.FindViewById<TextView>(Resource.Id.tv1).Typeface = Typeface.CreateFromAsset(Assets, "fonts/Montserrat_Light.ttf");
to change the typeface of a textview. But I am getting an error that 'The name 'assets' does not exist in the current context'
This is the fragment code
public class xFragment : Fragment
{
const string ARG_PAGE = "ARG_PAGE";
private int mPage;
public static xFragment newInstance(int page)
{
var args = new Bundle();
args.PutInt(ARG_PAGE, page);
var fragment = new xFragment ();
fragment.Arguments = args;
return fragment;
}
public override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
mPage = Arguments.GetInt(ARG_PAGE);
}
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
var view = inflater.Inflate(Resource.Layout.AgeLayout, container, false);
view.FindViewById<TextView>(Resource.Id.tv1).Typeface = Typeface.CreateFromAsset(Assets, "fonts/Montserrat_Light.ttf");
if (mPage == 2)
{
view = inflater.Inflate(Resource.Layout.AgeERLayout, container, false);
}
return view;
}
}
I found the solution and was so easy. I just had to use Activity.Assets

android fragment reloading (onCreate) each time when back Button pressed

I am new in android using fragments in my Project. first time my fragment is creating then api called and get data load in fragment. here when i clicked at any item i replaced fragment by another fragment there also another api called and load data to fragment.
now here problem situation generated for me.
from here i back Button pressed.
fragment reloading same as first time creating but it should be show data as i left before going to next fragment.
so please provide me solution how i can get same data as i left means savedInstanceState data.
im my first fragment getCategory method call Api and get Data first time when i choose any category i replace fragment with another fragment but when i m returning same getCategory method recall perform same process as it first time.
fragment should not call api method again on backpressed it should show same category on this i clicked before.
my first fragment where calling api......
public class LandingFragment 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 GridLayoutManager gridLayoutManager;
private static RecyclerView category_Grid;
private Fragment myFragment = null;
ProgressBar mProgressView;
View mLoginFormView;
private Category category;
private CategoryAdapter categoryAdapter;
private List<CategoryObject> rowListItem;
private String productId;
private OnFragmentInteractionListener mListener;
public LandingFragment() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* #param param1 Parameter 1.
* #param param2 Parameter 2.
* #return A new instance of fragment LandingFragment.
*/
// TODO: Rename and change types and number of parameters
public static LandingFragment newInstance(String param1, String param2) {
LandingFragment fragment = new LandingFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v= inflater.inflate(R.layout.fragment_landing, container, false);
return v;
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
initViews(view);
RecyclerViewListeners();
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
#Override
public void onAttach(Activity context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p/>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
private void initViews(final View v) {
mLoginFormView = (View)v.findViewById(R.id.mainView);
mProgressView = (ProgressBar)v.findViewById(R.id.login_progress);
category_Grid = (RecyclerView)v.findViewById(R.id.cat_grid);
category_Grid.setHasFixedSize(true);
gridLayoutManager = new GridLayoutManager(getActivity(), 3);
category_Grid.setLayoutManager(gridLayoutManager);
}
private void RecyclerViewListeners(){
category_Grid.addOnItemTouchListener(new RecyclerTouchListener(getActivity(), category_Grid, new ItemClickListener(){
#Override
public void onClick(View view, int position) {
String entityId = rowListItem.get(position).getCategoryId();
String catName = rowListItem.get(position).getName();
Integer ishave = rowListItem.get(position).getIshaveSubcategories();
if(ishave==1) {
myFragment = SubcategoryFragment.newInstance(""+catName, "" + entityId);
ActivityUtils.launchFragementWithAnimation(myFragment, getActivity());
}else{
myFragment = ProductListFragment.newInstance("", "" + entityId);
ActivityUtils.launchFragementWithAnimation(myFragment, getActivity());
}
}
#Override
public void onLongClick(View view, int position) {
}
}));
}
public void getCategory() {
showProgress(true);
String URL = getResources().getString(R.string.category_api);
StringRequest req = new StringRequest(Request.Method.POST,URL, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
VolleyLog.v("Response:%n %s", response);
Gson gson = new GsonBuilder().serializeNulls().create();
try {
JSONObject jsonObject = new JSONObject(response);
if (jsonObject.getString("status").equals(getResources().getString(R.string.response_success))){
category = gson.fromJson(response, Category.class);
rowListItem = category.getCategory();
if(navigationUpdated){
someEventListener.someEvent(rowListItem);
navigationUpdated = false;
}
Log.d("CATEGORYID::::::::",""+rowListItem.get(1).getCategoryId());
categoryAdapter = new CategoryAdapter(getActivity(),rowListItem);
category_Grid.setAdapter(categoryAdapter);
categoryAdapter.notifyDataSetChanged();
return;
}
else if (jsonObject.getString("status").equals(getResources().getString(R.string.login_Er_respose))){
Log.e("","ERRORRRRRR");
return;
}
} catch (JSONException e) {
showProgress(false);
Log.e("My App", "Could not parse malformed JSON: \"" + response + "\"");
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
showProgress(false);
VolleyLog.e("Error: ", error.getMessage());
}
}){
#Override
protected Map<String,String> getParams(){
Map<String,String> params = new HashMap<String, String>();
return params;
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String,String> params = new HashMap<String, String>();
params.put("Content-Type","application/x-www-form-urlencoded");
return params;
}
};
AppController.getInstance().addToRequestQueue(req);
}
#TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2)
private void showProgress(final boolean show) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
int shortAnimTime = getResources().getInteger(android.R.integer.config_shortAnimTime);
mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
mLoginFormView.animate().setDuration(shortAnimTime).alpha(
show ? 0 : 1).setListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
}
});
mProgressView.setVisibility(show ? View.VISIBLE : View.GONE);
mProgressView.animate().setDuration(shortAnimTime).alpha(
show ? 1 : 0).setListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
mProgressView.setVisibility(show ? View.VISIBLE : View.GONE);
}
});
} else {
mProgressView.setVisibility(show ? View.VISIBLE : View.GONE);
mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
}
}
You can check your rowListItem.size(), if it's size is 0 then call getCategory() service, otherwise load your data from your rowListItem. Here is sample code which I am using to load data from arraylist if it is not empty:
if (mArrayArticle.size() == 0) {
isDataLoading = true;
mRecyclerList.setVisibility(View.INVISIBLE);
getCategory();
} else {
mHomeItemAdapter = new HomeItemAdapter(getActivity(), mArrayArticle, this);
mRecyclerList.setAdapter(mHomeItemAdapter);
}
Here mArrayArticle is my ArrayList, Hope it will help you.
for more clarification i want to tell..
how i implement the #Bhvk_AndroidBee solution
fragment backpressed call onActivityCreated Method so first overridethis method in fragment
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
//here you can check null condition for rowListItem
}
}
inside onActivityCreated method I checked the condition like that
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if(rowListItem!=null){
categoryAdapter = new CategoryAdapter(getActivity(),rowListItem);
category_Grid.setAdapter(categoryAdapter);
categoryAdapter.notifyDataSetChanged();
}else {
//call the method for first time creating your view
getCategory();
}
}
hope this would be helpfull for more strugglers like me...

Android bundle is null after replacing fragment

I have two fragments which are VolleyFragment and AnotherFragment, setting VolleyFragment as the initial fragment. In this fragment, the bundle data is displaying ok. However, when I go to AnotherFragment, the app crashes. It says this error:
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String[] android.os.Bundle.getStringArray(java.lang.String)' on a null object reference
at com.example.rendell.volleyfragment.AnotherFragment.onCreateView(AnotherFragment.java:28)
MainActivity
public class MainActivity extends AppCompatActivity {
public static final String JSON_URL = "http://192.168.0.102/musicmania/music/getMF";
TextView id,name,email;
String[] ids, names, emails;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
id = (TextView) findViewById(R.id.id);
name = (TextView) findViewById(R.id.name);
email = (TextView) findViewById(R.id.email);
sendRequest();
}
private void sendRequest(){
StringRequest stringRequest = new StringRequest(JSON_URL,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
showJSON(response);
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(MainActivity.this, error.getMessage(), Toast.LENGTH_LONG).show();
}
});
RequestQueue requestQueue = Volley.newRequestQueue(this);
requestQueue.add(stringRequest);
}
private void showJSON(String json){
ParseJSON pj = new ParseJSON(json);
pj.parseJSON();
id.setText(ParseJSON.ids[0]);
name.setText(ParseJSON.titles[0]);
email.setText(ParseJSON.artists[0]);
FragmentManager fragmentTransaction = getFragmentManager();
android.app.FragmentTransaction transaction = fragmentTransaction.beginTransaction();
VolleyFragment squadFragment = new VolleyFragment();
AnotherFragment anotherFragment = new AnotherFragment();
Bundle bundle = new Bundle();
bundle.putStringArray("id", ParseJSON.ids);
bundle.putStringArray("name", ParseJSON.titles);
bundle.putStringArray("email", ParseJSON.artists);
squadFragment.setArguments(bundle);
anotherFragment.setArguments(bundle);
transaction.replace(R.id.containerView, squadFragment);
transaction.commit();
}
public void changeFragment(View view) {
FragmentManager fragmentTransaction = getFragmentManager();
android.app.FragmentTransaction transaction = fragmentTransaction.beginTransaction();
AnotherFragment anotherFragment = new AnotherFragment();
transaction.replace(R.id.containerView, anotherFragment);
transaction.commit();
}
}
VolleyFragment
public class VolleyFragment extends Fragment {
TextView id,name,email;
String[] ids,names,emails;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.volley_fragment, container, false);
id = (TextView) view.findViewById(R.id.id);
name = (TextView) view.findViewById(R.id.name);
email = (TextView) view.findViewById(R.id.email);
ids = getArguments().getStringArray("id");
names = getArguments().getStringArray("name");
emails = getArguments().getStringArray("email");
//jsonArray.setIds(id);
id.setText(/*jsonArray.getIds()*/ids[0]);
name.setText(names[0]);
email.setText(emails[0]);
return view;
}
}
AnotherFragment
public class AnotherFragment extends Fragment {
TextView id,name,email;
String[] ids,names,emails;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.another_fragment, container, false);
id = (TextView) view.findViewById(R.id.id);
name = (TextView) view.findViewById(R.id.name);
email = (TextView) view.findViewById(R.id.email);
ids = getArguments().getStringArray("id");
names = getArguments().getStringArray("name");
emails = getArguments().getStringArray("email");
//jsonArray.setIds(id);
id.setText(/*jsonArray.getIds()*/ids[0]);
name.setText(names[0]);
email.setText(emails[0]);
return view;
}
}
I'm having trouble following exactly what you're doing here, but I see a number of problems:
In showJSON, you new up a ParseJSON object and assign it to pj, but never make use of pj. Instead you reach statically into ParseJSON for the values to populate a Bundle. That seems really odd. I'd expect the pj instance to contain the data.
Typically one does not "new" up a fragment. The usual pattern is to use a static builder in the class of the fragment itself.
You're passing the same Bundle to two different fragments. Unless you know for a fact that's OK, try instead using a different Bundle for each one.
in showJSON, your AnotherFragment instance doesn't seem to be used at all
I don't see any place where changeFragment is called
You're passing string arrays in the Bundle, but you only ever use the first element in the array in the fragment. Consider just passing a single string instead?

ViewPager: Performing an Operation In Between Scrolls

Currently, the project in question is set up using a ViewPager which has an adapter capable of loading 4 different fragments. The last 3 Fragments are dependent upon the first fragment giving them a value (the SQL foreign key comes from the a value from the first item in the ViewPager).
My question is: how do I retrieve a value from the first Fragment's EditText, perform an SQL Operation and pass a value once the user attempts to "swipe" to the next tab?
Note, that I am trying to do this on swipe, and not via button. So far I have attempted to override OnPageScrolled, which yielded a null pointer when referring to the first fragment. I am assuming that the first fragment has been destroyed when I attempt to call it's hasPopulatedClassName() function
For Reference, the offending activity. Note the comment under OnPageScrolled
public class ActivityClassEdit extends FragmentActivity implements ViewPager.
private ClassEditPagerAdapter aPager;
//Views
private ViewPager vPager;
//Boolean telling us if we are good to move on to Criteria, People, or Links
private boolean mClassInserted;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_class_edit);
if(getIntent().hasExtra(CM.BKEY_PASSED_SEMESTERKEY)){
//Set the views
vPager=(ViewPager) findViewById(R.id.ace_pager);
//Instantiate the pager and set it
aPager=new ClassEditPagerAdapter(this, getIntent().getExtras().getLong(CM.BKEY_PASSED_SEMESTERKEY, -1));
vPager.setAdapter(aPager);
vPager.setOnPageChangeListener(this);
} else {
//TODO handle not having a semester key
}
}
//=============PageScrollListener==============
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
if(!mClassInserted) {
if (position == 1) {
//FragmentClassEdit fCE = (FragmentClassEdit) aPager.getRegisteredFragment(0);
FragmentClassEdit fCE = (FragmentClassEdit) aPager.getRegisteredFragment(0);
if (fCE.hasPopulatedClassName() == false) {
vPager.setCurrentItem(0);
Toast.makeText(this, getResources().getString(R.string.toast_typeInClassName), Toast.LENGTH_LONG).show();
} else {
//Save to shared Preferences, in case we have to delete on user cancellation
//null pointer here!!!
long mInsertedClassID= Long.getLong(fCE.insertClass());
getSharedPreferences(CM.SP, Activity.MODE_PRIVATE).edit().putLong(CM.SP_LASTINSERTEDCLASS, mInsertedClassID).apply();
aPager.setClassID(mInsertedClassID);
vPager.setCurrentItem(position);
}
}
} else {
vPager.setCurrentItem(position);
}
}
And here is the ViewPagerAdapter:
public class ClassEditPagerAdapter extends FragmentStatePagerAdapter{
private FragmentClassEdit fCE;
private Fragment fCrit;
private Fragment fLinks;
private Fragment fPeople;
private FragmentManager fragmentManager;
private String[] sTabText;
SparseArray<Fragment> registeredFragments = new SparseArray<Fragment>();
private Context ctx;
private long semID;
private long cID;
public ClassEditPagerAdapter(FragmentActivity context, long semesterID){
super(context.getSupportFragmentManager());
fragmentManager=context.getSupportFragmentManager();
ctx= context;
sTabText = ctx.getResources().getStringArray(R.array.cepa_titles);
cID=-1;
semID=semesterID;
}
public void setClassID(long classID){
cID=classID;
}
#Override
public Fragment getItem(int fragID) {
switch (fragID) {
//FragClassEdit
case 0:
fCE = FragmentClassEdit.newInstance(semID);
return fCE;
//FragTypeEdit
case 1:
fCrit = FragmentCriteriaEdit.newInstance(cID);
return fCrit;
//FragPeople
case 2:
fPeople = FragmentPeopleEdit.newInstance(cID);
return fPeople;
//FragLinks
case 3:
fLinks = FragmentLinkEdit.newInstance(cID);
return fLinks;
}
return null;
}
#Override
public Object instantiateItem(ViewGroup container, int position){
Fragment fragment = (Fragment) super.instantiateItem(container, position);
registeredFragments.put(position, fragment);
return fragment;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
registeredFragments.remove(position);
super.destroyItem(container, position, object);
}
public Fragment getRegisteredFragment(int position) {
return registeredFragments.get(position);
}
#Override
public int getCount() {
return 4;
}
#Override
public String getPageTitle(int position){
return sTabText[position];
}
}

how I get the current visible fragment from view pager Adapter..?

I have implemented these lines of code but it is not working .
pagerAdapter= new AbstractPagerAdapter(getSupportFragmentManager());
mViewPager = (ViewPager)findViewById(R.id.pager);
MyFragment frg = (MyFragment)pagerAdapter.getItem(mViewPager.getCurrentItem());
public class AbstractPagerAdapter extends FragmentPagerAdapter {
public AbstractPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
return AbstractDetailFragment.newInstance(objlist.get(position),position == notePosition ? true : false);
}
#Override
public int getCount() {
return objlist.size();
}
#Override
public CharSequence getPageTitle(int position) {
return objlist.get(position).getTitle();
}
}
To get the currently visible fragment instance try the following
viewPager.setOnPageChangeListener(this);
and in the following method
#Override
public void onPageSelected(int position) {
if (position == 0)
setFragmentFor(0);
if (position == 1)
setFragmentFor(1);
.
.
.
// Upto how many fragments you've in your ViewPager
}
so in the setFragmentFor() method you should write your own logic to get the new Instance of Fragment depending upon the argument value passed over the setFragmentFor().

Resources