I have set recycler view in one fragment which consist of 20 records.When I click on any one of cardview a swipeard is displayed in next Fragment.I am passing some data from cardview to swipecard.I need to set all 20 SwipeCards after moving to SwipeCard Fragment.But only one SwipeCard is displayed.
This is code for setting swipecard
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v=inflater.inflate(R.layout.temp_user_status_info, container, false);
swipeCardsView=(SwipeCardsView)v.findViewById(R.id.swipeCard);
infoAdapter=new CurrentInfoAdapter(info,getActivity());
swipeCardsView.retainLastCard(false);
swipeCardsView.enableSwipe(true);
person_name=getArguments().getString("name");
person_people=getArguments().getString("people");
person_estimate=getArguments().getString("estimate");
CurrentInfo currentInfo=new CurrentInfo();
currentInfo.setName(person_name);
currentInfo.setPeople(person_people);
currentInfo.setEstimate(person_estimate);
Log.i("name",person_name);
Log.i("people",person_people);
Log.i("estimate",person_estimate);
info.add(currentInfo);
swipeCardsView.setAdapter(infoAdapter);
return v;
This is code for RecyclerView Adapter from where I am passing data to SwipeCardView
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
final CurrentEntry current=filterList.get(position);
// holder.number.setText(current.getNo());
holder.Name.setText(current.getName());
holder.People.setText(current.getPeople());
holder.Estimate.setText(current.getEstimate());
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String name=current.getName();
String people=current.getPeople();
String estimate=current.getEstimate();
Bundle args=new Bundle();
args.putString("name",name);
args.putString("people",people);
args.putString("estimate",estimate);
// UserSatusInfo satusInfo=new UserSatusInfo();
// satusInfo.setArguments(args);
TempUserStatusInfo info=new TempUserStatusInfo();
info.setArguments(args);
AppCompatActivity activity=(AppCompatActivity)v.getContext();
// activity.getSupportFragmentManager().beginTransaction().replace(R.id.frame,satusInfo).addToBackStack("info").commit();
activity.getSupportFragmentManager().beginTransaction().replace(R.id.frame,info).addToBackStack("info").commit();
Toast.makeText(v.getContext(),name,Toast.LENGTH_SHORT).show();
Log.i("name",name);
}
});
How to get all Cards at a same time after clicking any one card from Recycclerview
You can pass you complete arraylist
bundle.putSerializable("key", ArrayList<T extends Serializable> list);
and then in fragment recieve
ArrayList<T extends Serializable> transactionList = (ArrayList<T extends Serializable>)getArguments().getSerializable("key");
Hope this helps.
Related
I have an expandable list view with a button and a textview in the group header.
I uses an adapter that implements the view holder.
I want to include a click event on the button such that I get the textview text that is in the group header and I want to pass the string to another fragment.
I also want to show the other fragment.
I am stuck as I can`t figure out,
How to read the textview value from the expandable listview in the fragment on the button click
and
How to pass the value of Title to another fragment.
Do I need to use
GViewHolder.myButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
}
or
public void onItemClick(AdapterView<?> parent, View view,int position, long id) {
});
Please note that I can`t see public void onItemClick being hit when the button is clicked!
I have implemented an adapter as follows:
Part of the code is
public class ListViewAdapter extends BaseExpandableListAdapter {
class GViewHolder {
public TextView Title;
public Button myButton;
}
GViewHolder.myButton.setFocusable(false);
GViewHolder.myButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// How to implement this in the fragment ???
}
});
}
Part of the fragment that implements the Adapter as follows:
private ListView eList = null;
InterFragmentNavigator interFragmentNavigator;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_event_list, container, false);
eList = (ListViewAdapter) view.findViewById(R.id.eView);
ListViewAdapter listDataAdapter = new ListViewAdapter(getActivity(), groupes);
eList.setAdapter(listDataAdapter);
eList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,int position, long id) {
// Here, I want to read the textview value of Title next to button
TextView textViewItem = ((TextView) view.findViewById(R.id.Title));
String Title = textViewItem.getText().toString();
**//Here, I want to call another fragment and pass Title as parameter.**
return view;
}
lets say you are creating new fragment from the click then add something like.
Fragment detailFragment = new Fragment();
Bundle bundle = new Bundle();
bundle.putString("TITLE", "your title");
detailFragment.setArguments(bundle);
Then do the transection here. Then in the detailFragment you can do
Bundle bundle = getArguments();
String title = bundle.getString("TITLE") ;
I have a fragment with a viewpager with adapter extending FragmentStatePagerAdapter with three slidable fragments inside. the main fragment has a static list of data, and three sub-fragments references and show the same list (don't ask why). The list item can be removed by a button inside the row layout or by clicking clear-all button after the list in each of those three fragments.
My problem is that after removing one or all the items with the buttons, sometimes i get an instant index out of bounds exception (no application code in stack trace, to find where the exception is coming from) or randomly sometimes removal work, but fragments nearby display old data with the extra item, and clicking to remove it ofcourse throws out of bounds exception, because after some debugging I can see that size of list passed to adapter to recreate the nearby fragment is lower by one (removal is successful) so I believe the list is not notified/invalidated correctly. Any help, since stacktrace can't help?
Btw I'm using FragmentStatePagerAdapter.POSITION_NONE to recreate the fragments with new data on each swipe, notifyDataSetChanged to notify the adapter of changed data, and invalidate() the listview in onViewCreated(), but they don't help.
relevant code:
Main Fragment
public class MainFragment extends BaseFragment<CategoryTreeItem> {
public static List<Map.Entry<EventTreeItem, String>> betList = new ArrayList<>();
...
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
ViewPager mViewPager = (ViewPager) view.findViewById(R.id.viewpager);
mViewPager.setAdapter(new MyPagerAdapter(getChildFragmentManager()));
SlidingTabLayout mSlidingTabLayout = (SlidingTabLayout) view.findViewById(R.id.sliding_tabs);
mSlidingTabLayout.setViewPager(mViewPager);
}
}
class MyPagerAdapter extends FragmentStatePagerAdapter {
private List<String> items;
public MyPagerAdapter(FragmentManager fm) {
super(fm);
items = getResources().getStringArray(R.array.three_categories);
}
#Override
public Fragment getItem(int i) {
Fragment fragment;
switch (i) {
case 0:
fragment = new FirstFragment();
return fragment;
case 1:
fragment = new SecondFragment();
return fragment;
case 2:
fragment = new ThirdFragment();
return fragment;
default:
return null;
}
}
...
#Override
public int getItemPosition(Object object) {
return FragmentStatePagerAdapter.POSITION_NONE;
}
}
Three fragments (they are needed since the layout and functionality is a bit different)
public class First/Second/ThirdFragment extends BaseListFragment<ArrayList<EventTreeItem>> {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_main, container, false);
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
MyListAdapter adapter = new MyListdapter(getActivity(), R.layout.item_first/second/thirdfragment, MainFragment.betList);
getListView().setItemsCanFocus(true);
View footerView = getLayoutInflater(savedInstanceState).inflate(R.layout.include_first/second/third_footer, getListView(), false);
getListView().addFooterView(footerView);
adapter.notifyDataSetChanged();
setListAdapter(adapter);
getListView().invalidate();
//handles REMOVE ALL button for all fragments footer button
Helper.setUpClearOption(footerView, adapter);
}
}
MyListAdapter
#CompileStatic
public class MyListAdapter extends ArrayAdapter<Map.Entry<EventTreeItem,String>> {
private int mResourceId;
private List<Map.Entry<EventTreeItem,String>> mObjects;
public MyListAdapter(Context context, int resource, List<Map.Entry<EventTreeItem,String>> objects) {
super(context, resource, objects);
mResourceId = resource;
mObjects = objects;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View view = convertView;
if (view == null) {
view = LayoutInflater.from(getContext()).inflate(mResourceId, parent, false);
}
//------setting a lot of text for textViews
// .....
//------
ImageView ivRemove = (ImageView) view.findViewById(R.id.ivRemove);
ivRemove.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Tried removing directly from adapter, not helping
// MyListAdapter.this.remove(mObjects.get(position));
MainFragment.betList.remove(position);
MyListAdapter.this.notifyDataSetChanged();
}
});
return view;
}
}
Remove All helper method (also returning instant OOB or not notifying neighbor fragments)
public static void setUpClearOption(View view, final ArrayAdapter adapter) {
ImageView ivRemoveAll = (ImageView) view.findViewById(R.id.ivRemoveAll);
ivRemoveAll.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
adapter.clear();
adapter.notifyDataSetChanged();
}
});
}
So any help is much appreciated!
I managed to fix My problem by creating three listadapters for each of my fragments (static adapters instantiaiting with null value ) and in onClick I check each of those three adapters if they are not null (since adapters are null until after onViewCreated, and it is called only when the current fragment is a neighbor). All three adapters use the same data.
I have a viewPager with say 4 pages. All 4 pages uses same Xml. When i do an event in 1st page somehow it always triggers in the last page.
Here is my PagerAdapter
#Override
public Object instantiateItem(ViewGroup container, int pos) {
View desktopView;
OnTouchListener tl = null;
desktopView = act.getLayoutInflater().inflate(
act.getViewPagerLayout(groupName), null);
RelativeLayout rr_appContainer, rr_dialogContainer;
ImageView rr_home_container = (ImageView) desktopView
.findViewById(R.id.imageView_forClick);
Button buttonChange = (Button)desktopView.findViewById(R.id.B1);
Button buttonDelete = (Button)desktopView.findViewById(R.id.B2);
rr_appContainer = (RelativeLayout) desktopView
.findViewById(R.id.rr_home_container);
rr_dialogContainer = (RelativeLayout) desktopView
.findViewById(R.id.rr_dialogView);
..........
buttonDelete.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
deletestuff();
}
buttonChange.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
changeColorOfStuff();
}
.....
return desktopView;
}
What is happening is, When i click on buttonChange from 1st page it supposed to change the color of text on 1st page, but actually it is changing color of the last page. Similarly buttonDelete is deleting color from last page.
Regardless of what page i am in, its reflecting those changes on last page.
Any help would be appreciated.
From the context given here, the deleteStuff() and changeColorOfStuff() can only be members of the Fragment/Activity that owns the adapter, or the adapter itself. So these methods can only act on members of those classes. ViewPager asks the adapter for the fragments it is going to display. However, the text in the fragment being shown by the ViewPager belong to the that fragment. To act on that text, you need a method that's a member of that fragment. The usual way to do this is to use a custom fragment. For example:
Custom Fragment (inner class):
public static class CustomFragment extends Fragment {
//members of the fragment
TextView yourTextView;
...
public static CustomFragment newInstance(int pos) {
CustomFragment fragment = new CustomFragment();
//get whatever info you need for this page
Bundle args = getInfoSomehow(pos);
fragment.setArguments(args)
return fragment;
}
#Override
public View onCreateView(Layout inflater, ViewGroup container, Bundle savedInstanceState) {
View root = inflater.inflate(....
yourTextView = root.findViewById(...) //this is the text view you want to change things in
//all the stuff you're currently doing in instantiateItem()
return root;
}
private void deleteStuff() {
//whatever you need to do. But notice that here it's acting on the TextView that belongs to this particular fragment
}
private void changeColorOfStuff() {...}
...
}
Then in your instantiateItem(...)
#Override
public Object instantiateItem(ViewGroup container, int pos) {
return CustomFragment.newInstance(pos);
}
I have seen Link1 for this issue but could understand it right. I have a fragment that loads a list. When i click the list item it opens another activity. But i press back button it loads the list again. I want it to be at the same scroll position where it was before. In above mentioned link it specifies to use flag but i haven't got the point.
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dashboard);
android.app.Fragment fragment = new MeFragment();
getFragmentManager().beginTransaction().replace(R.id.layout_FragmentsContainer, fragment).addToBackStack(null).commit();
}
}
public class MeFragment extends Fragment
{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
return inflater.inflate(R.layout.fragment_me, container, false);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
meLV = (ListView) getView().findViewById(R.id.lv_Inbox);
loadingListProgress = (ProgressBar) getView().findViewById(R.id.progress_LoadingList);
meList = new ArrayList<Message>();
meAdapter = new MessagesListAdapter(getActivity(), meList);
//addFooter();
meLV.setAdapter(meAdapter);
meLV.setOnItemClickListener(this);
pageCount = 0;
loadmoreProgressDialog = new ProgressDialog(getActivity());
loadmoreProgressDialog.setTitle("Please wait ...");
loadmoreProgressDialog.setMessage("Loading more ...");
loadmoreProgressDialog.setCancelable(true);
loadUserMessages();
meLV.setOnScrollListener(new EndlessScrollListener() {
#Override
public void onLoadMore(int page, int totalItemsCount) {
// TODO Auto-generated method stub
//addFooter();
loadmoreProgressDialog.show();
loadUserMessages();
}
});
}
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
// TODO Auto-generated method stub
Utils.showToast_msg(getActivity(), "MessageItemClicked");
ReferralDetailFragment fragment = new ReferralDetailFragment();
getFragmentManager().beginTransaction().replace(R.id.layout_FragmentsContainer, fragment).addToBackStack(null).commit();
}
}
public class ReferralDetailFragment extends Fragment implements OnClickListener {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.fragment_referraldetail,container, false);
linkToAcknowledge = (TextView) view.findViewById(R.id.lbl_Link_to_Acknowledge);
return view;
}
}
I implemented a simple solution for this in my app, basically when you press back to go to the fragment again, onCreateView() is called. Here in onCreateView() you have done all initialization, so we change
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.fragment_me, container, false);
/*
*Whatever you want to do
*
*/
return view;
}
to:
View view;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
if(view==null){
view = inflater.inflate(R.layout.fragment_me, container, false);
/*
*Whatever you want to do
*
*/
}
else{
((ViewGroup)view.getParent()).removeView(view);
}
return view;
}
Here, we move View view outside and make it a class variable. So if it is the first time the fragment is called, it is null and the initialization occurs, otherwise it goes to else black. Else block is required because onCreateView() adds whatever it returns as a child of the view's parent, so since view is already there, we remove it and onCreateView automatically adds it again.
According to our exchange in the comments, I completely deletde my answer and re-write a new one.
I copy/paste the code from one of my apps and removing the useless things and changing the names. Hope there is not too many typing mistakes, at that it is the minimum required to have it working.
When I pop back to FirstFragment from SecondFragment, the scroll position of FirstFragment is the same as when I clicked an item to load the SecondFragment.
Note that I don't extend FragmentActivity. I have an activity which loads the fragments.
Extend/modify to match your needs.
MainActivity :
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_layout);
}
}
FirstFragment Class :
public class FirstFragment extends Fragment implements OnItemClickListener {
private ListView mListView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.first_fragment_layout, container, false);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mListView = (ListView) getView().findViewById(R.id.listview_first_fragment);
mListView.setAdapter(mAdapter); // depends on your adapter
mListView.setOnItemClickListener(this);
}
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
mListView.setItemChecked(position, true);
//in case you need, set the bundle here, for example pass the position
Bundle arguments = new Bundle();
arguments.putInt("position", position);
SecondFragment secondFragment = new SecondFragment();
secondFragment.setArguments(arguments);
getFragmentManager().beginTransaction().replace(R.id.fragment_container, secondFragment).addToBackStack(null).commit();
}
}
SecondFragment Class :
public class SecondFragment extends Fragment {
private Integer mPosition;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.second_fragment_layout, container, false);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Bundle arguments = getArguments();
if (arguments == null) {
mPosition= 0;
} else {
mPosition= arguments.getInt("Position");
}
}
}
What you are trying to achieve may be done with help of savedInstanceState. i also had this kind of problem which i resolved by using add() method instead of replace() in transition.
If you can change your method or already not using add() than give it a shot.
and if add() method didn't do the trick then check the implementation of savedInstanceState.
correctly save instance state.
How to save states of fragment views.
I'm trying to create a viewpager where the user can tap a photo and the photo will take a 'highlighted' state.
I achieve the 'highlighted' state by setting a FrameLayout overlay above the image. The problem is when i swipe trough the pages the state is not only lost but it appears on non selected images.
This is my viewpager adapter:
public class ImageSliderAdapter extends FragmentPagerAdapter {
//Image ids from constants
private int[] Images = Constants.Images;
private int mCount = Images.length;
public ImageSliderAdapter$Adapter(FragmentManager fm) {
super(fm);
}
// The displayed fragment for each position
#Override
public FragmentImageSlider getItem(int position) {
return FragmentImageSlider.newInstance(Images[position];
}
#Override
public int getCount() {
return mCount;
}
}
And this is the fragment that the viewpager returns:
public class FragmentImageSlider extends Fragment {
//Image resource id to show
int imageResourceId;
//Image view of the pic displayed
ImageView image;
// View to indicate highlighted images
View highliteView;
public static FragmentImageSlider newInstance(int imageResourceId){
FragmentImageSlider f = new FragmentImageSlider();
Bundle b = new Bundle();
b.putInt("image", imageResourceId);
f.setArguments(b);
return f;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (getArguments() !=null) {
//get image resource id from extras
imageResourceId = getArguments().getInt("image");
}
View root = inflater.inflate(R.layout.displayLayout, null);
image = (ImageView) root.findViewById(R.id.imageView);
highliteView = root.findViewById(R.id.highliteView);
image.setImageResource(imageResourceId);
//When the image is clicked, toggle the highlighted state
image.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//toggle state
//this view has a selector and changes when selected
highliteView.setSelected(!highliteView.isSelected());
}
});
return root;
}
}
So my question is, how can i keep the highlighted state?
You can change the visibility of your highlight view instead of selected state.
By default set the visibility of highlight view as GONE and when the image is selected change it to visible.
highliteView.setVisibility(View.GONE);
// when the image is clicked show the highlighted view
image.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
highliteView.setVisibility(View.VISIBLE);
}
});
According to the [FragmentPagerAdapter document](view hierarchy may be destroyed when not visible),
The fragment of each page the user visits will be kept in memory, though its view hierarchy may be destroyed when not visible
The view maybe reloaded from default layout when it go out of the view, that's why the highlight state is lost.
You should keep the highlight state in your Fragment:
public MyFragment extends Fragment{
//variable to keep the state
private boolean highlight;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
//rest of your other code
image.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
highliteView.setSelected(!highliteView.isSelected());
//set the highlight state when clicked
highlight = !highliteView.isSelected();
}
});
return root;
}
//set the view state to the image view
public void onViewCreated(View view, Bundle savedInstanceState){
highliteView.setSelected(highlight);
}
}