Android viewpager just show data on last fragment view - android

I'm writing a simple app using fragment and viewpager to display data calling from webservice. Problem is viewpager creates 3 fragments at the first time, but data only view on the last fragment.
Here's my activity:
public class LineDetailTabs extends FragmentActivity {
//declare some variables here
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_line_detail_tabs);
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager
.beginTransaction();
PlaceholderFragment hf = new PlaceholderFragment();
fragmentTransaction.replace(R.id.container, hf);
fragmentTransaction.commit();
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
mViewPager.setCurrentItem(index);
}
This is my adapter,
list_nodep is a String array contains id of many deparments.
count is number of departments, also number of tabs will be created.
public class SectionsPagerAdapter extends FragmentStatePagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
noDep = list_nodep[position];
PlaceholderFragment fragment = new PlaceholderFragment();
Bundle args = new Bundle();
//put some agurments
fragment.setArguments(args);
return fragment;
}
#Override
public int getCount() {
return count;
}
}
And my fragment here, same layout xml file for all fragments.
public static class PlaceholderFragment extends Fragment {
public static View rootView;
public static TextView tvHeader;
public static TextView tvPO;
public static TextView tvLot;
// many textviews
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
activity = (LineDetailTabs) getActivity();
loadData(noDep, date, username, dbIP, dbName, dbUsername, dbPassword);
rootView = inflater.inflate(R.layout.fragment_line_detail_tabs, container, false);
tvHeader = (TextView) rootView.findViewById(R.id.txtHeader);
tvPO = (TextView) rootView.findViewById(R.id.txtPO);
tvLot = (TextView) rootView.findViewById(R.id.txtLOT);
// many textviews remaining...
return rootView;
}
public static void loadData(String aNoDep, String aDate, String aUsername, String aDbIP, String aDbName, String aDbUser, String aDbPass) {
RequestParams params = new RequestParams();
//put params
invokeWS(params);
}
public static void invokeWS(final RequestParams params) {
AsyncHttpClient client = new AsyncHttpClient();
client.get("http://...", params, new AsyncHttpResponseHandler() {
#Override
public void onSuccess(int statusCode, Header[] headers, String response) {
try {
// JSON Object
JSONObject obj = new JSONObject(response);
// When the JSON response has status boolean value assigned with true
JSONArray jArr = obj.getJSONArray("list");
// Display info detail on screen
obj = jArr.getJSONObject(0);
tvHeader.setText = obj.getString("NAME_DEP");
tvPO.setText = obj.getString("NO_PO");
tvLot.setText = obj.getString("NO_LOT");
//set text for all textviews
}
// When the response returned by REST has Http response code other than '200'
#Override
public void onFailure(int statusCode, Throwable error,
String content) {
// When Http response code is '404'
if (statusCode == 404) {
Toast.makeText(activity.getApplicationContext(), Constants.ERR_CODE_404, Toast.LENGTH_SHORT).show();
}
// When Http response code is '500'
else if (statusCode == 500) {
Toast.makeText(activity.getApplicationContext(), Constants.ERR_CODE_500, Toast.LENGTH_SHORT).show();
}
// When Http response code other than 404, 500
else {
Toast.makeText(activity.getApplicationContext(), Constants.ERR_CODE_, Toast.LENGTH_SHORT).show();
}
}
});
}
}
When debugging my app, I saw fragment onCreateView run 3 times continuously, and after that cursor jumps to onSuccess, so just last fragment displayed data. I think I put loadData() method or setText at the wrong place. Please help.

OK, finally I fixed it. That's my mistake, I didn't pass params from activity to fragment.
Just put params here
#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).
noDep = list_nodep[position];
Bundle bundle = new Bundle();
bundle.putString("NO_DEP", noDep);
bundle.putString("DATE", date);
bundle.putString("USERNAME", username);
bundle.putString("DB_IP", dbIP);
bundle.putString("DB_NAME", dbName);
bundle.putString("DB_USER", dbUsername);
bundle.putString("DB_PASS", dbPassword);
bundle.putString("SERVER_IP", serverIP);
PlaceholderFragment fragment = new PlaceholderFragment();
fragment.setArguments(bundle);
return fragment;
}
Then get these arguments in onCreateView(), and call loadData() method.
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_line_detail_tabs, container, false);
activity = (LineDetailTabs) getActivity();
noDep = getArguments().getString("NO_DEP");
date = getArguments().getString("DATE");
username = getArguments().getString("USERNAME");
dbIP = getArguments().getString("DB_IP");
dbName = getArguments().getString("DB_NAME");
dbUsername = getArguments().getString("DB_USER");
dbPassword = getArguments().getString("DB_PASS");
serverIP = getArguments().getString("SERVER_IP");
loadData(noDep, date, username, dbIP, dbName, dbUsername, dbPassword);
tvHeader = (TextView) rootView.findViewById(R.id.txtHeader);
tvPO = (TextView) rootView.findViewById(R.id.txtPO);
//...
return rootView;
}

Related

Fragment in ViewPager using FragmentPagerAdapter is blank the first time activity is loaded

I'm creating an app with vertical page adapter using FragmentStatePagerAdapter. The big issue i'm facing is, data is not displayed on the textview on first app launch but is displayed on scrolling the page. I believe the fragment view is delaying to create textview because, on my LoadAlbumDataCompleted() function inside Fragmentone.class, i'm able to print the data returned or also output via toast but is not getting populated to the textview.
Kindly help.
MainActivity.class
public class MainActivity extends FragmentActivity implements LoadAalbumsTotalListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mAdapter = new MainActivityVSlideAdapter(this, getSupportFragmentManager(), NUMBER_OF_PAGES);
mPager.setAdapter(mAdapter);
LoadTotalAlbumsNum.BindAlbumsTotalListener(this);
}
#Override
public void OnLoadAlbumsCompleted(String total) {
if(total.trim().equalsIgnoreCase("")){
NUMBER_OF_PAGES=0;
}else{
NUMBER_OF_PAGES=Integer.parseInt(total.trim());
}
mAdapter = new MainActivityVSlideAdapter(this, getSupportFragmentManager(), NUMBER_OF_PAGES);
mPager.setAdapter(mAdapter);
}
}
MainActivityVSlideAdapter.class Adapter
public class MainActivityVSlideAdapter extends FragmentStatePagerAdapter {
static int NUMBER_OF_PAGES;
private Context con;
public MainActivityVSlideAdapter(Context con, FragmentManager fm, int NUMBER_OF_PAGES) {
super(fm);
this.con=con;
this.NUMBER_OF_PAGES=NUMBER_OF_PAGES;
}
#Override
public int getCount() {
return NUMBER_OF_PAGES;
}
#Override
public Fragment getItem(int position) {
return FragmentOne.newInstance(position);
}
}
Fragmentone.class
public class FragmentOne extends Fragment implements LoadAlbumDataListener {
private static final String MY_NUM_KEY = "num";
private int mNum;
private TextView SaloonName;
private TextView location;
// You can modify the parameters to pass in whatever you want
public static FragmentOne newInstance(int num) {
FragmentOne f = new FragmentOne();
Bundle args = new Bundle();
args.putInt(MY_NUM_KEY, num);
f.setArguments(args);
return f;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//get argument from
mNum = getArguments() != null ? getArguments().getInt(MY_NUM_KEY) : 0;
session=new Session(getActivity());
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_one, container, false);
Methods methods=new Methods(getActivity());
// v.setBackgroundColor(mColor);
SaloonName = v.findViewById(R.id.SaloonName);
location=v.findViewById(R.id.location);
new LoadAlbumData(getActivity()).execute(getString(R.string.urlAddress)+"load-album-data.php", String.valueOf(mNum));
LoadAlbumData.BindLoadAlbumDataListener(this);
return v;
}
#Override
public void LoadAlbumDataCompleted(String s) {
JSONArray jsonPicsArray = null;
JSONObject jsonObj;
String BusinessLocation=null;
try {
jsonPicsArray = new JSONArray(s);
businessName = jsonObj.getString("businessName");
BusinessLocation = jsonObj.getString("location");;
}
Toast.makeText(getActivity(), businessName, Toast.LENGTH_LONG).show();
SaloonName.setText(businessName);
location.setText(BusinessLocation);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
From your code, it looks like, you are not setting the LoadAlbumDataListener correctly. Instead of statically setting the listener. Pass reference in constructor of your LoadAlbumData Asynctask
remove this line
LoadAlbumData.BindLoadAlbumDataListener(this);
replace
new LoadAlbumData(getActivity()).execute(getString(R.string.urlAddress)+"load-album-data.php", String.valueOf(mNum));
with
new LoadAlbumData(getActivity(), this).execute(getString(R.string.urlAddress)+"load-album-data.php", String.valueOf(mNum));
Modify your asynctask to have reference of LoadAlbumDataListener
Also as a good practice, never store strong reference of activity or fragment in your asynctask. Use WeakReference.

Same Fragment with listviews on different tabs

I would like to create an activity which shows 3 tabs. The first tab should show a user's uploaded photos the 2nd all the images a user liked, and 3rd the user's favorite images. All these data comes from a webservice.I would like to use the same fragment with it's layout file and call different URLs. The fragment implements a StringReader and populates a listview inside.
My problem is that I managed to load the Fragment in the first tab, but the second and third tabs remains empty. If I navigate to the last tab and started to navigate back, then the first tab remains empty and the second gets populated. I watched so many tutorials and red what I could reached but It seems that nothing has helped.
The Fragment instantiation in my Activity looks like this :
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#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).
switch (position) {
case 0:
return UsersSpheresFragment.newInstance();
case 1:
return UsersSpheresFragment.newInstance();
case 2:
return UsersSpheresFragment.newInstance();
default:
return null;
}
}
#Override
public int getCount() {
// Show 3 total pages.
return 3;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "SECTION 1";
case 1:
return "SECTION 2";
case 2:
return "SECTION 3";
}
return null;
}
}
my fragment is :
public class UsersSpheresFragment extends Fragment {
CircleImageView userImageFragment;
TextView userNameTextFragment;
TextView nrOfSpheresFragment;
LinearLayout loadingLayoutFragment;
ListView listview_spheresFragment;
public PhotosphereListAdapter adapter;
TextView nrOfLikes;
TextView nrOfSeens;
String userId="";
String userName = "";
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.my_spheres_fragment,container,false);
return view;
}
// newInstance constructor for creating fragment with arguments
public static UsersSpheresFragment newInstance() {
UsersSpheresFragment fragmentFirst = new UsersSpheresFragment();
return fragmentFirst;
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
userImageFragment = (CircleImageView) getActivity().findViewById(R.id.userImageFragment);
userNameTextFragment = (TextView) getActivity().findViewById(R.id.userNameTextFragment);
nrOfSpheresFragment = (TextView) getActivity().findViewById(R.id.nrOfSpheresFragment);
loadingLayoutFragment = (LinearLayout) getActivity().findViewById(R.id.loadingLayoutFragment);
listview_spheresFragment = (ListView) getActivity().findViewById(R.id.listview_spheresFragment);
nrOfLikes = (TextView)getActivity().findViewById(R.id.nrOfLikes);
nrOfSeens = (TextView)getActivity().findViewById(R.id.nrOfSeens);
GlobalUserData userData = (GlobalUserData)getActivity().getApplication();
Bundle bundle = this.getArguments();
if (bundle != null) {
userId = bundle.getString("userId","");
userName = bundle.getString("userName","");
userNameTextFragment.setText(userName);
}
else{
if (userData.getUserImageLink().length() > 0) {
LoadUserImage(userData.getName(), userData.getUserImageLink());
}
userNameTextFragment.setText(userData.getName());
}
//Log.i("TAG",userData.GetAllData());
if (userId.length() > 0)
loadImagesFromAPI(MainActivity.URL_DATA+"typ=mysphere&id="+userId);
else
loadImagesFromAPI(MainActivity.URL_DATA+"typ=mysphere&id="+userData.getUserId());
listview_spheresFragment.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//send the photosphereId to the Panoviewer fragment
Bundle bundle = new Bundle();
bundle.putString("Id", view.getTag().toString());
bundle.putString("Title", ((Photosphere) adapter.getItem(position)).getTitle());
bundle.putString("Description", ((Photosphere) adapter.getItem(position)).getDescription());
bundle.putString("ThumbUrl", ((Photosphere) adapter.getItem(position)).getImageUrl());
bundle.putBoolean("ShowUserLink", userId.length() > 0 ? false : true);
//create the fragment
SimpleFragment fragment = new SimpleFragment();
fragment.setArguments(bundle);
FragmentTransaction transaction = getActivity().getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.content_main, fragment);
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
transaction.addToBackStack(null);
transaction.commit();
}
});
}
public void LoadUserImage(String userName, String imageUrl){
ImageLoader imageLoader = CustomVolleyRequest.getInstance(getActivity()).getImageLoader();
Bitmap bm = imageLoader.get(imageUrl, ImageLoader.getImageListener(userImageFragment, android.R.color.white, android.R.color.white)).getBitmap();
userImageFragment.setImageBitmap(bm);
userNameTextFragment.setText(userName);
}
public void loadImagesFromAPI(final String Url) {
loadingLayoutFragment.setVisibility(View.VISIBLE);
StringRequest stringRequest = new StringRequest(com.android.volley.Request.Method.GET, Url,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
ArrayList<Photosphere> photospheres = new ArrayList<>();
JSONObject jsonObject = new JSONObject(response);
if(jsonObject.isNull("userModel") || jsonObject.getJSONObject("userModel").isNull("OtherImages")){
loadingLayoutFragment.setVisibility(View.GONE);
nrOfSpheresFragment.setText("No images");
}
else {
if (userId.length() >0){
LoadUserImage((jsonObject.getJSONObject("userModel")).getString("UserName"),(jsonObject.getJSONObject("userModel")).getString("ImgPath"));
}
photospheres = new WebServiceReader().processSpheresModelJsonData(jsonObject.getJSONObject("userModel"),"OtherImages");
loadingLayoutFragment.setVisibility(View.GONE);
//init adapter
adapter = new PhotosphereListAdapter(getActivity(), photospheres, (userId.length() > 0 ? false : true),true);
listview_spheresFragment.setAdapter(adapter);
nrOfSpheresFragment.setText(nrOfSpheresFragment.getText()+"("+listview_spheresFragment.getCount()+")");
nrOfLikes.setText((jsonObject.getJSONObject("userModel")).getString("TotalLikes"));
nrOfSeens.setText((jsonObject.getJSONObject("userModel")).getString("TotalViews"));
}
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
nrOfSpheresFragment.setText("An error occurred. Please try again!");
}
}
);
RequestQueue requestQueue = Volley.newRequestQueue(getActivity());
requestQueue.add(stringRequest);
}
#Override
public void onDestroy() {
super.onDestroy();
}
}
Update!
It seems that all of the fragments are loaded and overwritten in the first tab.
nrOfSpheresFragment.setText(nrOfSpheresFragment.getText()+"("+listview_spheresFragment.getCount()+")");
this line of code updates a textview and I can see that the textview is updated 3 times (25)(10)(5) which means the number of results. Only the last result's listview is visible
I figured out what was the problem.
When I used the fragment, (the fragment was created before, and used in other way) I didn't notice that when I initialize the controls in the page, I use getactivity() instead of rootview. So in order to make it work I changed those two as shown
userImageFragment = (CircleImageView) view.findViewById(R.id.userImageFragment);
userNameTextFragment = (TextView) view.findViewById(R.id.userNameTextFragment);
nrOfSpheresFragment = (TextView) view.findViewById(R.id.nrOfSpheresFragment);
loadingLayoutFragment = (LinearLayout) view.findViewById(R.id.loadingLayoutFragment);
listview_spheresFragment = (ListView) view.findViewById(R.id.listview_spheresFragment);
nrOfLikes = (TextView)view.findViewById(R.id.nrOfLikes);
nrOfSeens = (TextView)view.findViewById(R.id.nrOfSeens);
You can set variable to fragment, witch helps you to choose content you need
private String mUrl; //url of content
//set url of content via newInstanse() method
public static UsersSpheresFragment newInstance(String dataUrl) {
UsersSpheresFragment fragment = new UsersSpheresFragment();
Bundle arguments = new Bundle();
arguments.putInt(EXTRA_KEY_ULR, dataUrl);
fragment.setArguments(arguments);
return fragment;
}
//get url in onCreate
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle extras = getArguments();
if (extras == null || !extras.containsKey(EXTRA_KEY_URL))
throw new IllegalArgumentException("missing authorId argument");
mUrl = extras.getInt(EXTRA_KEY_URL);
//load your data
webService.loadData(mUrl);
}
another variant is set type of content via newIntanse(int type) method and choose data match it type in fragment#onCreate()

Not able to Update fragments text while swaping cards

I am working on a card swipe and card flip functionality and I am using ViewPager and fragments.
My problem is I am not able to update TextView inside fragments as I swipe the card from left to right or right to left but when I flip the card it update the UI.
I tried everything which is available over Internet but none of the soltuion is working for me.
I am following this link https://github.com/jamesmccann/android-view-pager-cards
Here is my code
public class CardContainerFragment extends Fragment {
private boolean cardFlipped = false;
static TextView textview;
public CardContainerFragment() {
setHasOptionsMenu(true);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_card_container, container, false);
LinearLayout ll = (LinearLayout)rootView.findViewById(R.id.layout);
rootView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
flipCard();
}
});
getChildFragmentManager()
.beginTransaction()
.add(R.id.container, new CardFrontFragment())
.commit();
Message msg = handler.obtainMessage();
msg.arg1 = 1;
handler.sendMessage(msg);
return rootView;
}
final Handler handler = new Handler(){
#Override
public void handleMessage(Message msg) {
int page = CardActivity.mViewPager.getCurrentItem();
int page_index = page+1;
String current_page = page_index + " of " + card_activity.deck_map.size();
CardActivity.tv.setText(current_page);
super.handleMessage(msg);
}
};
public void flipCard() {
Fragment newFragment = null;
Message msg = handler.obtainMessage();
msg.arg1 = 1;
handler.sendMessage(msg);
if (cardFlipped) {
newFragment = new CardFrontFragment();
} else {
newFragment = new CardBackFragment();
}
getChildFragmentManager()
.beginTransaction()
.setCustomAnimations(
R.animator.card_flip_right_in, R.animator.card_flip_right_out,
R.animator.card_flip_left_in, R.animator.card_flip_left_out)
.replace(R.id.container, newFragment)
.commit();
cardFlipped = !cardFlipped;
}
public static class CardFrontFragment extends Fragment {
public CardFrontFragment() { }
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_card, container, false);
textview = (TextView)rootView.findViewById(R.id.card_front);
String card_front_string = card_activity.arraylst.get(CardActivity.mViewPager.getCurrentItem());
Log.e("current Item",CardActivity.mViewPager.getCurrentItem()+"");
String complete_text = card_front_string +" \n \n + \n Tap now to flip this card.";
textview.setText(complete_text);
return rootView;
}
}
public static class CardBackFragment extends Fragment {
public CardBackFragment() { }
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_card_back, container, false);
TextView textview = (TextView)rootView.findViewById(R.id.card_back);
textview.setMovementMethod(new ScrollingMovementMethod());
String card_front_string = card_activity.arraylst.get(CardActivity.mViewPager.getCurrentItem());
String deck_data = card_activity.deck_map.get(card_front_string);
textview.setText(deck_data);
return rootView;
}
}
Here is my adapter code
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
setContentView(R.layout.card_example);
tv = (TextView)findViewById(R.id.tv_card_number);
tv1 = (TextView)findViewById(R.id.tv_card_index);
FragmentManager m = getFragmentManager();
CardPagerAdapter adapter = new CardPagerAdapter(m);
index = getIntent().getStringExtra("index");
card_activity.cardCounter = Integer.parseInt(index);
int count = card_activity.cardCounter;
int final_count = count+1;
String current_page = final_count+" of "+card_activity.deck_map.size();
//CardActivity.tv.setText(current_page);
mViewPager = (ViewPager) findViewById(R.id.view_pager);
// mViewPager.setAllowedSwipeDirection(CustomViewPager.SwipeDirection.all);
mViewPager.setAdapter(adapter);
mViewPager.setCurrentItem(card_activity.cardCounter);
//mViewPager.setOffscreenPageLimit(1);
//mViewPager.setOnPageChangeListener(new pagechangelistener())
//Log.e("current Item",CardActivity.mViewPager.getCurrentItem()+"");
}catch(Exception e){
e.printStackTrace();
}
}
public class CardPagerAdapter extends android.support.v13.app.FragmentStatePagerAdapter {
public CardPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int i) {
mViewPager.setOffscreenPageLimit(0);
int page = mViewPager.getCurrentItem();
int page_index = page+1;
String current_page = " of " + card_activity.deck_map.size();
tv.setText(current_page);
tv1.setText(String.valueOf(page_index));
CardContainerFragment cardContainerFragment = new CardContainerFragment();
cardContainerFragment.current_index_front = page;
cardContainerFragment.current_index_back = page;
String card_front_string = card_activity.arraylst.get(page);
CardContainerFragment.complete_text_front = card_front_string +" \n \n + \n Tap now to flip this card.";
Bundle b = new Bundle();
b.putInt("index",page);
CardContainerFragment.complete_text_back = card_activity.deck_map.get(card_front_string);
cardContainerFragment.setArguments(b);
return cardContainerFragment;
}
#Override
public int getCount() {
int len = card_activity.deck_map.size();
return len;
}
#Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
}
Please let me know what I am doing wrong here.
Thanks in advance
Finally I am able to do this with some efforts.
After searching, I get to know that getItems (The method in CardPagerAdapter) is called two times because Android creates one extra fragments for smooth transition and I was sending or getting wrong position of fragments from getItems.
By letting the android to create one extra fragment and by sending correct position I am able to solve this issue.
Here is my updated code
public class CardActivity extends android.support.v4.app.FragmentActivity {
public TextView tv;
public static String index=null;
public static ViewPager mViewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
setContentView(R.layout.card_example);
tv = (TextView)findViewById(R.id.tv_card_number);
FragmentManager m = getFragmentManager();
CardPagerAdapter adapter = new CardPagerAdapter(m);
index = getIntent().getStringExtra("index");
card_activity.cardCounter = Integer.parseInt(index);
int count = card_activity.cardCounter;
int final_count = count+1;
String current_page = final_count+" of "+card_activity.deck_map.size();
mViewPager = (ViewPager) findViewById(R.id.view_pager);
mViewPager.setOffscreenPageLimit(0);
mViewPager.setAdapter(adapter);
mViewPager.setCurrentItem(card_activity.cardCounter);
String current_page_temp =final_count+" of " + card_activity.deck_map.size();
tv.setText(current_page_temp);
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
Log.e("aaa",position+"");
String current_page = position+1 + " of " + card_activity.deck_map.size();
tv.setText(current_page);
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
}catch(Exception e){
e.printStackTrace();
}
}
public class CardPagerAdapter extends android.support.v13.app.FragmentStatePagerAdapter {
public CardPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int i) {
CardContainerFragment cardContainerFragment = new CardContainerFragment();
Bundle b = new Bundle();
b.putInt("index",i);
cardContainerFragment.setArguments(b);
return cardContainerFragment;
}
#Override
public int getCount() {
int len = card_activity.deck_map.size();
return len;
}
#Override
public int getItemPosition(Object object) {
return POSITION_NONE;
}
}
}
==================================================================
public class CardContainerFragment extends Fragment {
private boolean cardFlipped = false;
int current_index=0;
static int pos = 0;
public CardContainerFragment() {
/*setHasOptionsMenu(true);*/
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_card_container, container, false);
LinearLayout ll = (LinearLayout)rootView.findViewById(R.id.layout);
rootView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
flipCard();
}
});
pos = getArguments().getInt("index");
getChildFragmentManager()
.beginTransaction()
.add(R.id.container, new CardFrontFragment().newInstance(pos))
.commit();
card_activity.tempCounter = card_activity.tempCounter+1;
return rootView;
}
public void flipCard() {
Fragment newFragment = null;
CardFrontFragment cardFrontFragment = null;
CardBackFragment cardBackFragment = null;
if (cardFlipped) {
newFragment = CardFrontFragment.newInstance(CardActivity.mViewPager.getCurrentItem());
} else {
newFragment = cardBackFragment.newInstance(CardActivity.mViewPager.getCurrentItem());
}
getChildFragmentManager()
.beginTransaction()
.setCustomAnimations(
R.animator.card_flip_right_in, R.animator.card_flip_right_out,
R.animator.card_flip_left_in, R.animator.card_flip_left_out)
.replace(R.id.container, newFragment)
.commit();
cardFlipped = !cardFlipped;
}
public static class CardBackFragment extends Fragment {
public CardBackFragment() { }
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView_back = inflater.inflate(R.layout.fragment_card_back, container, false);
TextView textview_back = (TextView)rootView_back.findViewById(R.id.card_back);
textview_back.setMovementMethod(new ScrollingMovementMethod());
String text = getArguments().getString("back_text");
textview_back.setText(text);
return rootView_back;
}
static CardBackFragment newInstance(int position) {
CardBackFragment cardBackFragment = new CardBackFragment();
Bundle args = new Bundle();
String card_front_string = card_activity.arraylst.get(position);
String text = card_activity.deck_map.get(card_front_string);
args.putString("back_text", text);
cardBackFragment.setArguments(args);
return cardBackFragment;
}
}
public static class CardFrontFragment extends Fragment {
public CardFrontFragment() { }
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView_front = null;
rootView_front = inflater.inflate(R.layout.fragment_card, container, false);
TextView textview_front = (TextView)rootView_front.findViewById(R.id.card_front);
String text = getArguments().getString("front_text");
textview_front.setText(text);
return rootView_front;
}
static CardFrontFragment newInstance(int position) {
CardFrontFragment cardFrontFragment = new CardFrontFragment();
Bundle args = new Bundle();
String card_front_string = card_activity.arraylst.get(position);
String text = card_front_string +" \n \n + \n Tap now to flip this card.";
args.putString("front_text", text);
cardFrontFragment.setArguments(args);
return cardFrontFragment;
}
}
}
As #david-rawson says
Don't use static fields CardActivity.mViewPager. See https://developer.android.com/guide/components/fragments.html#CommunicatingWithActivity
Reason for this is that the ViewPager might/will create the views of your fragments before they are displayed to ensure you get that smooth animation that people love ViewPagers for. So the mViewPager calls a number of fragments createView() function at the same time, and at that time the mViewPager has an index for .getCurrentItem() which goes to the CardContainer on the page being viewed.
A better option would be for you to pass CardContainerFragment a String argument with the value for "completeText" which you want it to display whenever it creates either CardBackFragment or CardFrontFragment.
Go through this for more details.
You just have to set data to text view which is used in CardFrontFragment.
Here when ever a swipe happens onCreateView() of CardContainerFragment is called.
You are adding CardFrontFragment every time when onCreateView() is called. you need to use text view of CardFrontFragment instead of using textview of activity.
Just replace CardActivity.tv.setText(current_page);
with textView.setText(current_page);
Make sure the textview you have used in CardFrontFragment is available at class level.
you are using static fragments so textview must be static.
private static TextView textView=null;
Hope this will work for you :)
Have you tried this:
tv.post(new Runnable() {
#Override
public void run() {
CardActivity.tv.setText(current_page);
}
});
I did something similar wihtin my App, and I manage the display of my TextView into the OnCreateView, with a switch case.
I tried to implent your code but did not have all your materials (like custom animator).
You should then try something like that:
public class CardContainerFragment extends AppCompatActivity {
private boolean cardFlipped = false;
static TextView textview;
/*public CardContainerFragment() {
setHasOptionsMenu(true);
}*/
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.your_activity_name);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// Create the adapter that will return a fragment for each of the three
// primary sections of the activity.
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
/*
The {#link ViewPager} that will host the section contents.
*/
ViewPager mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
mViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
// This method will be invoked when a new page becomes selected.
#Override
flipCard();
#Override
public void onPageSelected(int position) {
}
// This method will be invoked when the current page is scrolled
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
// Code goes here
}
// Called when the scroll state changes:
// SCROLL_STATE_IDLE, SCROLL_STATE_DRAGGING, SCROLL_STATE_SETTLING
#Override
public void onPageScrollStateChanged(int state) {
// Code goes here
}
});
}
#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_welcome, 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);
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
/**
* The fragment argument representing the section number for this
* fragment.
*/
private static final String ARG_SECTION_NUMBER = "section_number";
public PlaceholderFragment() {
}
/**
* Returns a new instance of this fragment for the given section
* number.
*/
public static PlaceholderFragment newInstance(int sectionNumber) {
PlaceholderFragment fragment = new PlaceholderFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
//Initializing data
Context context = getContext();
View rootView = inflater.inflate(R.layout.fragment_card, container, false);
TextView textView = (TextView) rootView.findViewById(R.id.txtView);
int fragment = getArguments().getInt(ARG_SECTION_NUMBER);
switch (fragment)
{
case 1: //front card
String card_front_string = card_activity.arraylst.get(CardActivity.mViewPager.getCurrentItem());
Log.e("current Item",CardActivity.mViewPager.getCurrentItem()+"");
String complete_text = card_front_string +" \n \n + \n Tap now to flip this card.";
textview.setText(complete_text);
getChildFragmentManager()
.beginTransaction()
.add(R.id.container, new CardFrontFragment())
.commit();
Message msg = handler.obtainMessage();
msg.arg1 = 1;
handler.sendMessage(msg);
return rootView;
case 2: //back card
TextView textview = (TextView)rootView.findViewById(R.id.card_back);
textview.setMovementMethod(new ScrollingMovementMethod());
String card_front_string = card_activity.arraylst.get(CardActivity.mViewPager.getCurrentItem());
String deck_data = card_activity.deck_map.get(card_front_string);
textview.setText(deck_data);
getChildFragmentManager()
.beginTransaction()
.add(R.id.container, new CardFrontFragment())
.commit();
Message msg = handler.obtainMessage();
msg.arg1 = 1;
handler.sendMessage(msg);
return rootView;
default:
return rootView;
}
}
}
final Handler handler = new Handler(){
#Override
public void handleMessage(Message msg) {
int page = CardActivity.mViewPager.getCurrentItem();
int page_index = page+1;
String current_page = page_index + " of " + card_activity.deck_map.size();
CardActivity.tv.setText(current_page);
super.handleMessage(msg);
}
};
public void flipCard() {
Message msg = handler.obtainMessage();
msg.arg1 = 1;
handler.sendMessage(msg);
getChildFragmentManager()
.beginTransaction()
.setCustomAnimations(
R.animator.card_flip_right_in, R.animator.card_flip_right_out,
R.animator.card_flip_left_in, R.animator.card_flip_left_out)
.replace(R.id.container, newFragment)
.commit();
}
/**
* A {#link FragmentPagerAdapter} that returns a fragment corresponding to
* one of the sections/tabs/pages.
*/
public class SectionsPagerAdapter extends FragmentPagerAdapter {
SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#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);
}
#Override
public int getCount() {
// Show 2 total pages.
return 2;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "SECTION 1";
case 1:
return "SECTION 2";
}
return null;
}
}
The textView is displayed on your page, and when selecting the change, the content of your textview will be changed.

ListViewFragment (Fragment that contains ListView) only created once, at the first time

I'm trying to update ListView's data after downloaded JSON data, but it didn't work because onCreate and onCreateView methods are only working at first time.
I noticed it when I put debugging point to that two methods but the debugging line never entered there. The response json is correct, but the UI couldn't be updated by parsing ListViewFragment.init(myNewDataList).
Here is my ListViewFragment,
public class ListViewFragment extends Fragment{
ListView listView;
ArrayList<Incident> incidentLists;
public static ListViewFragment init(ArrayList<Incident> incidentLists) {
ListViewFragment listViewFragment = new ListViewFragment();
listViewFragment.setIncientLists(incidentLists);
return listViewFragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_listview, container,
false);
initUI(view);
adapter = new ListViewAdapter(getActivity(), incidentLists);
adapter.notifyDataSetChanged();
listView.setAdapter(adapter);
return view;
}
public ArrayList<Incident> getIncientLists() {
return incidentLists;
}
public void setIncientLists(ArrayList<Incident> incientLists) {
this.incidentLists = incientLists;
}
}
And I parse the data to fragment after the JSON downloaded like following snippet, this is AsyncHttpClient's onSuccess method.
#Override
public void onSuccess(int statusCode, Header[] headers,
String content) {
try {
ArrayList<Incident> incidentList = new ArrayList<Incident>();
JSONObject content_ = new JSONObject(content);
JSONArray response = content_.getJSONArray("nodes");
for (int i = 0; i < response.length(); i++) {
JSONObject nodeObj = response.getJSONObject(i)
.getJSONObject("node");
Incident incident = Utils.parseNodeObjectToIncident(nodeObj);
incidentList.add(incident);
}
Fragment fragment = ListViewFragment.init(incidentList);
Utils.replaceFragment(fragment, MainActivity.this);
} catch (JSONException e) {
Toast.makeText(getApplicationContext(),"JSON Exception", Toast.LENGTH_LONG).show();
}
}
I doubt that my ListViewFragment only happen once at the first time because it is confusing with BackStack and transaction stuffs at Utils.replaceFragment().
public static void replaceFragment(Fragment fragment,
AppCompatActivity activity) {
String backStateName = fragment.getClass().getName();
String fragmentTag = backStateName;
FragmentManager fragmentManager = activity.getSupportFragmentManager();
boolean fragmentPopped = fragmentManager.popBackStackImmediate(
backStateName, 0);
if (!fragmentPopped
&& fragmentManager.findFragmentByTag(fragmentTag) == null) {
FragmentTransaction fragmentTransaction = fragmentManager
.beginTransaction();
fragmentTransaction.replace(R.id.frame_container, fragment,
fragmentTag);
// fragmentTransaction.add(R.id.frame_container, fragment);
fragmentTransaction
.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
fragmentTransaction.addToBackStack(backStateName);
// fragmentTransaction.commitAllowingStateLoss();
fragmentTransaction.commitAllowingStateLoss();
}
}
Any Help?
Basically your problem is that you are not able to update list when you have got latest set of information from server.
I would have solved this problem with the below code:
In list view adapter keep a method as written below:
public class ListFragmentAdapter extends <your adapter extension>{
private Context context;
private List<Incident> incidents;
//constructor
public ListFragmentAdapter (Context context,List<Incident> initialIncidentList){
this.context = context;
this.incidents = initialIncidentList;
}
public void updateListFragment(List<Incident> latestIncidents){
incidents.addAll(latestIncidents);
this.notifyDataSetChanged();
}
}
Comment below if you have any doubts

How to send data from Activity to Fragment

I know there are many topics about this here. I have also read documentation many times but I can't find the best way to pass data from activity to fragment.
I want to be able to show the results of my Searchable activity in two differents layouts (list and map) using swipe Views with tabs. I have to pass 2 data to the fragments: "currentLocation" which is the current user location and "result" which is a list of objects.
I have omited some parts of my code to make it more understandable.
SearchableActivity.java
public class SearchableActivity extends ActionBarActivity implements TabListener {
List<PlaceModel> result = new ArrayList<PlaceModel>();
private SearchView mSearchView;
private String currentLocation;
AppSectionsPagerAdapter mAppSectionsPagerAdapter;
ViewPager mViewPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_searchable);
final ActionBar actionBar = getSupportActionBar();
actionBar.setHomeButtonEnabled(true);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
mAppSectionsPagerAdapter = new AppSectionsPagerAdapter(getSupportFragmentManager());
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mAppSectionsPagerAdapter);
mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
#Override
public void onPageSelected(int position) {
actionBar.setSelectedNavigationItem(position);
}
});
actionBar.addTab(actionBar.newTab().setText("List").setTabListener(this));
actionBar.addTab(actionBar.newTab().setText("Map").setTabListener(this));
// get currentLocation here
handleIntent(getIntent());
}
#Override
protected void onNewIntent(Intent intent) {
handleIntent(intent);
}
private void handleIntent(Intent intent) {
if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
final String query = intent.getStringExtra(SearchManager.QUERY);
// get result here
}
}
#Override
public void onTabReselected(Tab arg0, FragmentTransaction arg1) {
// TODO Auto-generated method stub
}
#Override
public void onTabSelected(Tab tab, FragmentTransaction arg1) {
mViewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(Tab arg0, FragmentTransaction arg1) {
// TODO Auto-generated method stub
}
}
PlaceListFragment.java
public class PlaceListFragment extends Fragment {
ListView listViewData;
PlaceAdapter placeAdapter;
List<PlaceModel> result = new ArrayList<PlaceModel>();
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_list, container, false);
Bundle args = getArguments();
listViewData = (ListView) rootView.findViewById(android.R.id.list);
// I will pass result and currentLocation here
placeAdapter = new PlaceAdapter(getActivity(), R.layout.fragment_list_item, result, currentLocation);
listViewData.setAdapter(placeAdapter);
return rootView;
}
}
AppSectionsPagerAdapter.java
public class AppSectionsPagerAdapter extends FragmentPagerAdapter {
final int PAGE_COUNT = 2;
public AppSectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int arg0) {
Bundle data = new Bundle();
switch(arg0) {
case 0:
PlaceListFragment fragment1 = new PlaceListFragment();
fragment1.setArguments(data);
return fragment1;
default:
PlaceListFragment fragment2 = new PlaceListFragment();
fragment2.setArguments(data);
return fragment2;
}
}
#Override
public int getCount() {
return PAGE_COUNT;
}
}
Find fragment in Activity onCreate and set data to a method you write in your fragment:
ExampleFragment rf = (ExampleFragment) getSupportFragmentManager().findFragmentById(R.id.exampleFragment);
if(rf!=null){
rf.setExample(currentExample);
}
"CurrentExample" is whatever you want to send in to your "setExample" method in your fragment.
public void setExample(ExampleObject currentExample){
currentExampleInFragment = currentExample;
}
You can use the data in onActivityCreated method of Fragment.
Not sure is this is a good solution or not, but I found it the easiest one for passing objects.
Usually the activities will have a reference to their fragments. In your SearchableActivity.java are you also loading PlaceListFragment.java either in setContentView(activity_searchable.xml); or you need to create a instance of the fragment and add/replace a fragment using FragmentTransaction.
you can find a good example here on how to communicated between fragments or between activity & fragment.
Training link
Bundle bundle = new Bundle();
bundle.putString("edttext", "From Activity");
// set Fragmentclass Arguments
Fragmentclass fragobj = new Fragmentclass();
fragobj.setArguments(bundle);
and in Fragment onCreateView method:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
String strtext = getArguments().getString("edttext");
return inflater.inflate(R.layout.fragment, container, false);
}
see detail answer here..
"send data from Activity to Fragment"
Activity:
Bundle bundle = new Bundle();
bundle.putString("message", "Alo Stackoverflow!");
FragmentClass fragInfo = new FragmentClass();
fragInfo.setArguments(bundle);
transaction.replace(R.id.fragment_single, fragInfo);
transaction.commit();
Fragment:
Reading the value in the fragment
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Bundle bundle = this.getArguments();
String myValue = bundle.getString("message");
...
...
...
}
or
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
String myValue = this.getArguments().getString("message");
...
...
...
}
Create one Session model class and in Activity set the values you want to data needs to be send then in Fragment you can get that values from Session model class
eg. from your activity u can set like this.
AllEventDetails.getInstance().setEvent_description(event_Description);
AllEventDetails.getInstance().setDj_name(dj_name);
AllEventDetails.getInstance().setMusic_theme(music_theme);
AllEventDetails.getInstance().setClub_name(club_name);
AllEventDetails.getInstance().setDate(event_date);
AllEventDetails.getInstance().setBanner_image_path(banner_image_path);
AllEventDetails.getInstance().setEvent_title(event_title);
and from your Fragment u can retrive like this.
AllEventDetails.getInstance().getClub_name()
.........
Creating Session model class is like this.
public class AllEventDetails {
private static AllEventDetails mySession ;
private String event_description;
private String dj_name;
private String music_theme;
private String club_name;
private String date;
private String banner_image_path;
private String event_title;
private AllEventDetails() {
event_description = null;
dj_name = null;
music_theme = null;
club_name = null;
date = null;
banner_image_path = null;
event_title = null;
}
public static AllEventDetails getInstance() {
if( mySession == null ) {
mySession = new AllEventDetails() ;
}
return mySession ;
}
public void resetSession() {
mySession=null;
}
public String getEvent_description() {
return event_description;
}
public void setEvent_description(String event_description) {
this.event_description = event_description;
}
public String getDj_name() {
return dj_name;
}
public void setDj_name(String dj_name) {
this.dj_name = dj_name;
}
public String getMusic_theme() {
return music_theme;
}
public void setMusic_theme(String music_theme) {
this.music_theme = music_theme;
}
public String getClub_name() {
return club_name;
}
public void setClub_name(String club_name) {
this.club_name = club_name;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public String getBanner_image_path() {
return banner_image_path;
}
public void setBanner_image_path(String banner_image_path) {
this.banner_image_path = banner_image_path;
}
public String getEvent_title() {
return event_title;
}
public void setEvent_title(String event_title) {
this.event_title = event_title;
}
}

Categories

Resources