can not pass data from on fragment to other in ViewPager - java

I have an Activity with viewpager in one page should be EditText and other page be the TextView, get data from first fragment to show in second view but I'm struggling because of lack of knowledge, I have Main Activity as
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
viewPager.setAdapter(new MyPagerAdapter(getSupportFragmentManager()));
}
private class MyPagerAdapter extends FragmentPagerAdapter {
public MyPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int pos) {
switch(pos) {
case 0: return EditFragment.newInstance("FirstFragment, Instance 1");
case 1: {
Log.e("TAG", " is " + new EditFragment().getTag());
return PreviewFragment.newInstance(new EditFragment().getTag());
}
default: return EditFragment.newInstance("ThirdFragment, Default");
}
}
#Override
public int getCount() {
return 2;
}
}
}
main layout is
<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/viewpager"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
EditFragment is
public class EditFragment extends Fragment {
public EditFragment(){}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_editor, container, false);
EditText tv = (EditText) v.findViewById(R.id.content);
tv.setText(getArguments().getString("msg"));
return v;
}
public static EditFragment newInstance(String text) {
EditFragment f = new EditFragment();
Bundle b = new Bundle();
b.putString("msg", text);
f.setArguments(b);
return f;
}
}
PreviewFragment
public class PreviewFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_markdown, container, false);
TextView tvView = (TextView) v.findViewById(R.id.markdownView);
tvView.loadMarkdown(getArguments().getString("msg"));
return v;
}
public static PreviewFragment newInstance(String text) {
PreviewFragment f = new PreviewFragment();
Bundle b = new Bundle();
b.putString("msg", text);
f.setArguments(b);
return f;
}
}
there I do not know how to pass data from EditFragment to PreviewFragment, please help.
I'm newbie to Fragments please help me.
UPDATE
I have changed
public class PreviewFragment extends Fragment {
private TextView textView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_markdown, container, false);
textView = (TextView) v.findViewById(R.id.title);// initialized here
return v;
}
public void b_updateText(String t){
Log.e("LOAD TXT", t);// Here I can get data Data is available
textView.setText(t); // but Here I get NPE, don't know why.
}
}
but Here I get NPE, don't know why.
and EditFragment is
public class EditFragment extends Fragment {
public EditFragment(){}
private static Bundle bundle = null;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_editor, container, false);
final EditText tv = (EditText) v.findViewById(R.id.content);
final PsgerActivity mainActivity = ( PsgerActivity) getActivity();
mainActivity.message= tv.getText().toString();
tv.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
bundle = new Bundle();
bundle.putString("md", tv.getText().toString());
Log.e("BUNDLE", bundle.getString("md"));// Data is available
}
#Override
public void afterTextChanged(Editable editable) {
}
});
return v;
}
public static EditFragment newInstance() {
EditFragment f = new EditFragment();
f.setArguments(bundle);
return f;
}
}
MainActivity is
public class MainActivity extends AppCompatActivity {
public String message;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
viewPager.setAdapter(new MyPagerAdapter(getSupportFragmentManager()));
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
if (position == 1) {
PreviewFragment fragmentB = new PreviewFragment();
EditFragment ef = EditFragment.newInstance();
try{
Log.e("ACTIVITY", ef.getArguments().getString("md"));// Data is available
} catch (Exception e){
e.printStackTrace();
}
fragmentB.b_updateText(ef.getArguments().getString("md"));
}
}
#Override
public void onPageSelected(int position) {
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
}
private class MyPagerAdapter extends FragmentPagerAdapter {
public MyPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int pos) {
switch(pos) {
case 0: return EditFragment.newInstance();
case 1: return new PreviewFragment();
default: return EditFragment.newInstance();
}
}
#Override
public int getCount() {
return 2;
}
}
}
but Here I get NPE, don't know why.

Have you had a chance go through android docs?
Communicating with Other Fragments
Of course you can use Otto or EventBus library.
And also have a look at this answer.

Create a variable in MainActivity and access that variable from fragment through
MainActivity mainActivity = ( MainActivity) getActivity();
mainActivity.message="Hai from EditFragment"
Check out the below code:
public class MainActivity extends AppCompatActivity {
public String message;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
viewPager.setAdapter(new MyPagerAdapter(getSupportFragmentManager()));
}
private class MyPagerAdapter extends FragmentPagerAdapter {
public MyPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int pos) {
switch(pos) {
case 0: return EditFragment.newInstance("FirstFragment, Instance 1");
case 1: {
Log.e("TAG", " is " + new EditFragment().getTag());
return PreviewFragment.newInstance(new EditFragment().getTag());
}
default: return EditFragment.newInstance("ThirdFragment, Default");
}
}
#Override
public int getCount() {
return 2;
}
}
}
EditFragment is
public class EditFragment extends Fragment {
public EditFragment(){}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_editor, container, false);
EditText tv = (EditText) v.findViewById(R.id.content);
tv.setText(getArguments().getString("msg"));
MainActivity mainActivity = ( MainActivity) getActivity();
mainActivity.message="Hai from EditFragment"
//store data through message variable inside activity
return v;
}
}
PreviewFragment
public class PreviewFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_markdown, container, false);
TextView tvView = (TextView) v.findViewById(R.id.markdownView);
MainActivity mainActivity = ( MainActivity) getActivity();
tvView.loadMarkdown(mainActivity.message);// get data through message variable of main activity
return v;
}
}

With FragmentManager, we can access another fragment from our current fragment by calling findFragmentByTag(<tag of target fragment>).
// First Fragment, from we're sending data
public class MyFragmentA extends Fragment {
EditText A_input;
Button A_enter;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View myFragmentView = inflater.inflate(R.layout.fragment_a, container, false);
A_input = (EditText)myFragmentView.findViewById(R.id.a_input);
A_enter = (Button)myFragmentView.findViewById(R.id.a_enter);
A_enter.setOnClickListener(A_enterOnClickListener);
return myFragmentView;
}
OnClickListener A_enterOnClickListener = new OnClickListener(){
#Override
public void onClick(View arg0) {
String textPassToB = A_input.getText().toString();
String TabOfFragmentB = ((MainActivity)getActivity()).getTabFragmentB();
MyFragmentB fragmentB = (MyFragmentB)getActivity()
.getSupportFragmentManager()
.findFragmentByTag(TabOfFragmentB);
fragmentB.b_updateText(textPassToB);
Toast.makeText(getActivity(),
"text sent to Fragment B:\n " + TabOfFragmentB,
Toast.LENGTH_LONG).show();
}};
}
// Second Fragment, where we'll get data
public class MyFragmentB extends Fragment {
TextView b_received;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View myFragmentView = inflater.inflate(R.layout.fragment_b, container, false);
b_received = (TextView)myFragmentView.findViewById(R.id.b_received);
String myTag = getTag();
((MainActivity)getActivity()).setTabFragmentB(myTag);
Toast.makeText(getActivity(),
"MyFragmentB.onCreateView(): " + myTag,
Toast.LENGTH_LONG).show();
return myFragmentView;
}
public void b_updateText(String t){
b_received.setText(t);
}
}

Related

Use a view from a fragment in main activity

I'm pretty new in android development and I have some questions about communication between fragments and main activity.
I didn't success to solve my problem in my particular case. What I want to do is to modify the alpha of a view inside a fragment (something like a card) when scrolling from one fragment to the one with this view. I tried different things but I failed (null pointer exception), you can see some experiments in a comment. Here is my code and my architecture:
Fragment with the view:
public class VideoviewFragment extends BaseFragment {
/* public View card;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootview = inflater.inflate(R.layout.fragment_videoview, container, false);
card = (View) rootview.findViewById(R.id.card_video);
return rootview;
}
public void setalphacard(float value){
card.setAlpha(value);
}*/
public static VideoviewFragment create() {
return new VideoviewFragment();
}
#Override
public int getLayoutResId() {
return R.layout.fragment_videoview;
}
#Override
public void inOnCreateView(View root, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
}
}
Base fragment:
public abstract class BaseFragment extends Fragment {
private View mRoot;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
mRoot = inflater.inflate(getLayoutResId(), container, false);
inOnCreateView(mRoot, container, savedInstanceState);
return mRoot;
}
#LayoutRes
public abstract int getLayoutResId();
public abstract void inOnCreateView(View root, #Nullable ViewGroup container,#Nullable Bundle savedInstanceState);
}
Main Activity:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Viewpager
final ViewPager viewPager = (ViewPager) findViewById(R.id.am_view_pager);
final MainPagerAdapter adapter = new MainPagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(adapter);
// tabview et viewpager
viewPager.setCurrentItem(1);
// Changement couleurs swipe
viewPager.setBackgroundColor(Color.rgb(135,206,250));
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
if(position == 1) {
viewPager.setBackgroundColor((Integer) new ArgbEvaluator().evaluate(positionOffset, Color.rgb(135,206,250),Color.rgb(240,15,45)));
//videoviewFragment.setalphacard(positionOffset);
}
if(position == 0) {
viewPager.setBackgroundColor((Integer) new ArgbEvaluator().evaluate(positionOffset, Color.TRANSPARENT,Color.rgb(135,206,250)));
}
}
#Override
public void onPageSelected(int position) {
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
}
}
Adapter:
public class MainPagerAdapter extends FragmentPagerAdapter {
public MainPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position){
case 0:
return CameraFragment.create();
case 1:
return OptionFragment.create();
case 2:
return VideoviewFragment.create();
}
return null;
}
#Override
public int getCount() {
return 3;
}
}
XML VideoviewFragment
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/relativeLayout0"
android:layout_width="match_parent"
android:layout_height="match_parent">
<View
android:id="#+id/card_video"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="70dp"
android:background="#drawable/card_background_video"/>
</RelativeLayout>
(I know there is no instance of my fragment in this activity...)
I found few similar topics on StackOverflow like this one Use view from fragment xml file, but I'm doing something wrong...
Thanks for your help!

Opening Fragment from DialogFragment

I want to open Fragment (MirrorFragment.java) from DialogFragment (CatalogueHatDialog.java) and show in Fragment the image that I have chosen in DialogFragment.
I tried to use the code from here: Opening Fragment from a DialogFragment (replacing the Dialogs parent) and other questions on stackoverflow, but it didn’t help.
The image isn’t shown and there are no errors.
I think my mistake is in Fragment, but I’m not sure.
CatalogueHatDialog.java:
public class CatalogueHatDialog extends DialogFragment {
private static List<Hat> listHats;
private GridView gvMain;
public static CatalogueHatDialog newInstance(List<Hat> hats) {
listHats = hats;
Bundle args = new Bundle();
CatalogueHatDialog catalogueHatDialog = new CatalogueHatDialog();
catalogueHatDialog.setArguments(args);
return catalogueHatDialog;
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.catalogue, null);
gvMain = (GridView) v.findViewById(R.id.gvCatalogue);
gvMain.setAdapter(new CatalogueGridAdapter(listHats, getActivity()));
gvMain.setOnItemClickListener(new GridView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
dismiss();
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.btnCapture, MirrorFragment.PlaceholderFragment.newInstance(position));
ft.addToBackStack(null);
ft.commit();
}
});
getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
return v;
}
}
MirrorFragment.java (not relevant methods are excluded):
public class MirrorFragment extends Fragment implements SurfaceHolder.Callback {
private static View viewMirrorLayout;
private static View cameraViewControl;
private SurfaceHolder cameraSurfaceHolder = null;
public ViewPager btnCapture;
private Activity activity;
private SectionsPagerAdapter mSectionsPagerAdapter;
private ImageView btnCatalogue;
private static int hatId;
public MirrorFragment() {
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
this.activity = (Activity) context;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
SurfaceView cameraSurfaceView;
viewMirrorLayout = inflater.inflate(R.layout.fragment_mirror, container, false);
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
activity.getWindow().setFormat(PixelFormat.TRANSLUCENT);
activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
cameraSurfaceView = (SurfaceView) viewMirrorLayout.findViewById(R.id.cameraSurfaceViewFragment);
cameraSurfaceHolder = cameraSurfaceView.getHolder();
cameraSurfaceHolder.addCallback(this);
cameraSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
LayoutInflater layoutInflater = LayoutInflater.from(getActivity());
RelativeLayout.LayoutParams layoutParamsControl = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,
RelativeLayout.LayoutParams.MATCH_PARENT);
cameraViewControl = layoutInflater.inflate(R.layout.cambutton, null);
btnCapture = (ViewPager) cameraViewControl.findViewById(R.id.btnCapture);
mSectionsPagerAdapter = new SectionsPagerAdapter(getFragmentManager());
btnCapture.setAdapter(mSectionsPagerAdapter);
btnCapture.addOnPageChangeListener(new MyPageChangeListener());
((FrameLayout) viewMirrorLayout).addView(cameraViewControl, layoutParamsControl);
btnCatalogue = (ImageView) viewMirrorLayout.findViewById(R.id.ivCatalog);
btnCatalogue.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
CatalogueHatDialog dialog = CatalogueHatDialog.newInstance(getAllHats());
dialog.show(getFragmentManager(), "catalogueDialog");
}
});
return viewMirrorLayout;
}
public static class PlaceholderFragment extends Fragment {
private static final String ARG_SECTION_NUMBER = "section_number";
private ImageView ivHat;
public PlaceholderFragment() {
}
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) {
View slidingLayout = inflater.inflate(R.layout.sliding_fragment_hat, container, false);
ivHat = (ImageView) slidingLayout.findViewById(R.id.ivHat);
ivHat.setBackgroundResource(getAllHats().get(getArguments().getInt(ARG_SECTION_NUMBER) - 1).getPhoto());
return slidingLayout;
}
}
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
return PlaceholderFragment.newInstance(position + 1);
}
#Override
public int getCount() {
return getAllHats().size();
}
}
private class MyPageChangeListener extends ViewPager.SimpleOnPageChangeListener {
#Override
public void onPageSelected(int position) {
hatId = position;
}
}
}
I found the mistake.
So here is what is needed to be written:
CatalogueHatDialog.java:
public class CatalogueHatDialog extends DialogFragment {
...
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
dismiss();
getTargetFragment().onActivityResult(position, Activity.RESULT_OK, getActivity().getIntent());
}
});
...
}
}
MirrorFragment.java:
…
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
btnCapture.setCurrentItem(requestCode);
}

Where to place EventBus.getDefault().unregister in BaseAdapter

Friends, I've spent enough time to find an answer to my question(here and on android's site) But no luck.
Here is the logic:
From DialogFragment upon finishing putting user's data he clicks OK button:
import de.greenrobot.event.EventBus;
...
public class AddDialogFragment extends DialogFragment implements
DialogInterface.OnClickListener {
...
public void onClick(DialogInterface dialog, int which) {
StringBuilder date = new StringBuilder(today.getText().subSequence(0,
today.getText().length()));
date = (date.toString().equals(getString(R.string.today))) ? new StringBuilder("20150104") : date;
int weight = 89;
String[] bsi = rb.getSelectedItems();
String[] gsi = rg.getSelectedItems();
DatabaseManipulation dm = new DatabaseManipulation(getActivity());
dm.run(date, weight, bsi, gsi);
dm.destroy();
DialogDataModel toSend = new DialogDataModel(weight, date.toString(), bsi, gsi);
/*
Context activity = getActivity();
if (activity instanceof WDActivity)
((WDActivity) activity).updateListItemFragment();
*/
EventBus.getDefault().post(new UpdateItemEvent(toSend));
Log.d(LOG_TAG, "send event");
Toast.makeText(getActivity(), R.string.saved_data, Toast.LENGTH_LONG).show();
}
...
Event is successfully sent to Adapter class which is registered for receiving this event:
...
import de.greenrobot.event.EventBus;
public class ItemsAdapter extends BaseAdapter implements ListAdapter {
private static final String LOG_TAG = "Logs";
private ArrayList<DialogDataModel> list = new ArrayList<DialogDataModel>();
private Context activity;
public ItemsAdapter (ArrayList<DialogDataModel> list, Context context) {
this.list = list;
this.activity = context;
registerEventBus();
}
#Override
public int getCount() {
return list.size();
}
#Override
public Object getItem(int pos) {
return list.get(pos);
}
#Override
public long getItemId(int pos) {
return pos;
//just return 0 if your list items do not have an Id variable.
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View view = convertView;
if (view == null) {
LayoutInflater inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.row_item, null);
}
DialogDataModel curData = list.get(position);
TextView itemDate = (TextView)view.findViewById(R.id.item_date);
itemDate.setText(curData.getDate());
TextView itemWeight = (TextView)view.findViewById(R.id.item_weight);
itemWeight.setText( Integer.toString(curData.getWeight()) );
TextView itemEvents = (TextView)view.findViewById(R.id.item_events);
itemEvents.setText(curData.getEventsShort());
//Handle buttons and add onClickListeners
ImageButton editBtn = (ImageButton)view.findViewById(R.id.item_edit_btn);
editBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (activity instanceof WDActivity)
((WDActivity) activity).AddNewData(v, list.get(position));
notifyDataSetChanged();
}
});
ImageButton deleteBtn = (ImageButton) view.findViewById(R.id.item_delete_btn);
deleteBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String date = list.get(position).getDate();
DatabaseManipulation dm = new DatabaseManipulation(activity);
dm.deleteItem(date);
dm.destroy();
list.remove(position);
notifyDataSetChanged();
}
});
return view;
}
public void registerEventBus(){
if (!EventBus.getDefault().isRegistered(this)) EventBus.getDefault().register(this);
Log.d(LOG_TAG, "Registred from adapter");
}
public void unregisterEventBus(){
EventBus.getDefault().unregister(this);
}
public void onEventMainThread(UpdateItemEvent event) {
Log.d(LOG_TAG, "Event fired!");
list = DialogDataModel.replaceFieldsInArray(list,event.getModel());
notifyDataSetChanged();
}
}
After clicking OK in dialog window the user sees the list of items and the item he's updated is up to date. Without this logic he sees the old version of this item item in the list and to refresh the list he needs to relaunch the app.
Yes, it's working with EventBus.
But as you can see here in the class there is no place for unregistering it from listening for UpdateItemEvent. Since there are no destructors in java(I don't believe that garbage collector should do this for me) I should handle this. Moreover the class registeres as listener in constructor (it happens several times, that's why you see this ugly if statement(if (!EventBus.getDefault().isRegistered(this))) You may ask me why not getting this adapter through Activity (there is the only one in the app) I tried building a chain AddDialogFragment -> WDActivity -> PlaceholderFragment -> ItemsAdapter
//AddDialogFragment
Context activity = getActivity();
if (activity instanceof WDActivity)
((WDActivity) activity).updateListItemFragment();
//WDActivity --beginTransaction().replace does not work here
...
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_wd);
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.
mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
}
...
public void updateListItemFragment() {
android.support.v4.app.FragmentManager fragmentManager = getSupportFragmentManager();
android.support.v4.app.Fragment currentFragment = fragmentManager.findFragmentById(R.id.container);
if (currentFragment instanceof PlaceholderFragment && currentFragment != null) {
fragmentManager.beginTransaction().remove(currentFragment).commit();
fragmentManager.beginTransaction().add(R.id.container, currentFragment).commit();
((PlaceholderFragment)currentFragment).fillList();
}
//PlaceholderFragment
public class PlaceholderFragment extends Fragment {
private static final String LOG_TAG = "Logs";
private static final String ARG_SECTION_NUMBER = "section_number";
private ListView listViewItem;
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;
}
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if(getArguments().getInt(ARG_SECTION_NUMBER)==1)
return onCreateViewInputChart(inflater, container, savedInstanceState);
if(getArguments().getInt(ARG_SECTION_NUMBER)==2)
return onCreateViewManual(inflater, container, savedInstanceState);
return onCreateViewInputData(inflater, container, savedInstanceState);
}
private View onCreateViewManual(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_howto, container, false);
return rootView;
}
private View onCreateViewInputData(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_list_data, container, false);
findViewsByIdListItem(rootView);
fillList();
return rootView;
}
private View onCreateViewInputChart(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_chart, container, false);
return rootView;
}
//listViewItems
private void findViewsByIdListItem(View v) {
listViewItem = (ListView) v.findViewById(R.id.listViewItems);
}
public void fillList(){
Context activity = getActivity();
DatabaseManipulation dm = new DatabaseManipulation(activity);
ArrayList<DialogDataModel> aldm = dm.getItemsList();
dm.destroy();
ItemsAdapter innerAdapter = new ItemsAdapter(aldm, activity);
listViewItem.setAdapter(innerAdapter);
( (BaseAdapter) listViewItem.getAdapter() ).notifyDataSetChanged();
}
#Override
public void onAttach(Context activity) {
super.onAttach(activity);
}
#Override
public void onDetach(){
super.onDetach();
}
}
//SectionsPagerAdapter - just for your information
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 PlaceholderFragment.newInstance(position);
}
#Override
public int getCount() {
return 3;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "Enter your data";
case 1:
return "Chart";
case 2:
return "How to use it";
}
return null;
}
}
//ItemsAdapter is placed higher
This did not work. Finally I found out that the bottleneck is in linking PlaceholderFragment and ListAdapter: listViewItem is null everywhere except onCreateViewInputData. I could not figure out why. Google didn't give me the answer and I took it as a magic. Btw due to this feature I cannot use PlaceholderFragment's onAttach and onDetach for saying ItemsAdapter to register/unregister for receiving the event. This:
#Override
public void onAttach(Context activity) {
super.onAttach(activity);
( (ItemsAdapter) listViewItem.getAdapter() ).registerEventBus();
}
doesn't work for the same reason listViewItem is null. Maybe there is some way to manage with this more accurately?
Finally I cope with this: the bottleneck is in linking PlaceholderFragment and ListAdapter: listViewItem is null everywhere except onCreateViewInputData . Below is rewised SectionsPagerAdapter:
public class SectionsPagerAdapter extends FragmentPagerAdapter {
Context activity;
SparseArray<Fragment> registeredFragments = new SparseArray<Fragment>();
public SectionsPagerAdapter(FragmentManager fm, Context activity) {
super(fm);
this.activity = activity;
}
#Override
public Fragment getItem(int position) {
// getItem is called to instantiate the fragment for the given page.
return PlaceholderFragment.newInstance(position);
}
#Override
public int getCount() {
return 3;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return activity.getString(R.string.chart);
case 1:
return activity.getString(R.string.weight_diary);
case 2:
return activity.getString(R.string.how_to);
}
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);
//maybe use adapater.getRegisteredFragment(viewPager.getCurrentItem());
}
}
and here is my call to the widget in the one of 3 fragments:
public void updateListItemFragment() {
android.support.v4.app.Fragment inputData = mSectionsPagerAdapter.getRegisteredFragment(1);
ListView lv = ((PlaceholderFragment)inputData).listViewItem;
//for test purposes I refill listview with no items - here you need to hand filled BaseAdapter instance: CustomAdapter innerAdapter = new CustomAdapter(ArrayList<yourDataModel>, getContext());
lv.setAdapter(null);
}
And as you've may already wondered there is no need for event bus anymore. Btw if the fragment is not crated yet you need to check it: details are here. Thanks to CommonsWare for quik reply and advice.

SectionsPagerAdapter - No view found for id for fragment

I have a App with a Slidingmenu where i can pick different Fragment, which displays different kind of ListFragments.
The ListFragments will be filled by JSON from my Database Server.
If you Click on one of the Listitems, a new Fragment is shown which contains more Details about the selected Listitem.
public void updateList(final Activity a, final ListFragment L) {
adapter = new SimpleAdapter(a, mCommentList,
R.layout.single_comment, new String[] {TAG_PIC_ID,TAG_CATEGORY, TAG_ACTIVITY, TAG_DATUM, TAG_AKTUSR, TAG_MAXUSR, TAG_GENDER, /*TAG_POST_ID,*/ TAG_TITLE, TAG_MESSAGE,
TAG_USERNAME }, new int[] { R.id.imgrow, R.id.category, R.id.activity/*R.id.id*/ , R.id.datum, R.id.aktusr, R.id.maxusr, R.id.gender, /*R.id.category,*/ R.id.title, R.id.message,
R.id.username });
L.setListAdapter(adapter);
ListView lv = L.getListView();
lv.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
int intid = (int)id;
Details nextFrag= new Details();
L.getFragmentManager().beginTransaction()
.replace(R.id.frame_container, nextFrag, "Test")
.addToBackStack(null)
.commit();
}
});
}
When i call the function from a "single" fragment its no problem and the DetailPage is shown.
The Problem is when i call the function from a TabbedActivity with a SectionsPagerAdapter.
The TabbedActivity
package info.androidhive.slidingmenu;
public class TabbedActivity extends Fragment {
SectionsPagerAdapter mSectionsPagerAdapter;
public static final String TAG = TabbedActivity.class.getSimpleName();
ViewPager mViewPager;
public static TabbedActivity newInstance() {
return new TabbedActivity();
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.activity_item_one, container, false);
mSectionsPagerAdapter = new SectionsPagerAdapter(
getChildFragmentManager());
mViewPager = (ViewPager) v.findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
return v;
}
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
Fragment fragment = new newEntrys();
switch (position) {
case 0:
fragment = new newEntrys();
break;
case 1:
fragment = new oldEntrys();
break;
default:
break;
}
return fragment;
}
#Override
public int getCount() {
return 2;
}
#Override
public CharSequence getPageTitle(int position) {
Locale l = Locale.getDefault();
switch (position) {
case 0:
return "Aktuelle Einträge";
case 1:
return "Vergangene Einträge";
}
return null;
}
}}
The TabbedActivity contains the 2 Fragments newEntry and oldEntry which are nearly equal.
package info.androidhive.slidingmenu.fragments;
public class RegisterdEvents_new extends ListFragment{
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.read, container, false);
return rootView;
}
public void startTask(){
Read SO = new Read();
Load LEvt = SO.new Load(getActivity(), this, "NEW");
LEvt.execute();
}
public void onResume() {
startTask();
super.onResume();
}
}
So the function updateList above is called in
Load LEvt = SO.new Load(getActivity(), this, "NEW");
But the problem is that i always get the Error
No view found for id 0x7f0a000f (package:id/frame_container) for fragment Details{e3992e2 #0 id=0x7f0a000f Test}
Someone of you can help me to solve this problem?

Please help me with Instance

I have two buttons "start hotel1" and "start hotel2".
when you click on them, I create a fragment in which ViewPager:
public class PagerContainer extends Fragment {
static final int PAGE_COUNT = 2;
private String hotel;
public PagerContainer(String hotel) {
this.hotel = hotel;
}
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.pager_container, null);
ViewPager pager = (ViewPager) v.findViewById(R.id.pager);
PagerAdapter pagerAdapter = new MyFragmentPagerAdapter(getActivity().getSupportFragmentManager());
pager.setAdapter(pagerAdapter);
pager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageSelected(int position) {
Log.d("LOG", "onPageSelected, position = " + position);
}
#Override
public void onPageScrolled(int position, float positionOffset,
int positionOffsetPixels) {
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
return v;
}
private class MyFragmentPagerAdapter extends FragmentPagerAdapter {
public MyFragmentPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
return CalendarView.newInstance(position,hotel);
}
#Override
public int getCount() {
return PAGE_COUNT;
}
#Override
public CharSequence getPageTitle(int position) {
return "title";
}
}
}
I load it in another fragment that takes different parameters, depending on the button:
public class CalendarView extends Fragment {
static final String ARGUMENT_PAGE_NUMBER = "arg_page_number";
static final String ARGUMENT_HOTEL = "arg_hotel";
private int pageNumber;
private String hotel;
static CalendarView newInstance(int page,String hotel) {
Log.d("myLOG","newInstance");
CalendarView calendarView = new CalendarView();
Bundle arguments = new Bundle();
arguments.putInt(ARGUMENT_PAGE_NUMBER, page);
arguments.putString(ARGUMENT_HOTEL, hotel);
calendarView.setArguments(arguments);
return calendarView;
}
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.calendar, null);
pageNumber = getArguments().getInt(ARGUMENT_PAGE_NUMBER);
hotel = getArguments().getString(ARGUMENT_HOTEL);
...
return v;
}
public class NewThread extends AsyncTask<String, Void, String> {
protected String doInBackground(String... strings) {
...
}
#Override
protected void onPostExecute(String s) {
....
}
}
}
First pressing any key data normally loaded. After they loaded I click on the second button, and I have an empty screen. Log just says that the instance is not created. I need something to clean or rebuild? how?
case CONFEENCE_GRUP_NODE:
Fragment conference;
switch (position2) {
case HOLIDAY:
conference = new PagerContainer("holiday");
fragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
fragmentManager.beginTransaction().replace(R.id.content_frame, conference).commit();
break;
case CITY:
conference = new PagerContainer("city");
fragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
fragmentManager.beginTransaction().replace(R.id.content_frame, conference).commit();
break;
}
break;
Don't ever override the Fragment constructor, because they MUST have an empty constructor. Create the same newInstance method in your PagerContainer, and grab the parameter from it:
private static final String ARGUMENT_PAGE_HOTEL = "arg_page_hotel";
public PagerContainer() {
}
public static PagerContainer newInstance(String hotel) {
PagerContainer container = new PagerContainer();
Bundle arguments = new Bundle();
arguments.putString(ARGUMENT_PAGE_HOTEL, hotel);
container.setArguments(arguments);
return container;
}
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.pager_container, null);
hotel = getArguments().getString(ARGUMENT_PAGE_HOTEL);
...
return v;
}

Categories

Resources