I have Fragment Activity which contains a Framelayout for fragment transition. A fragment named LeadActiviy extends SherlockListFragment contains Asynctask, in AsyncTask's method onPostExcute contents else block statement. In else block current fragment replaced by ItemNotFound extends Fragment. After set the contents of ItemNotFound in framelayout when press back button it's current state persist & not appear its previous fragment. Please help me to solve issue-
Code of AsyncTask's method onPostExecute from LeadActivity ...
protected void onPostExecute(String file_url){
pDialog.dismiss();
//FragmentManager fm=getFragmentManager();
//final FragmentTransaction ft=fm.beginTransaction();
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
if(success==1){
// TODO Auto-generated method stub
ListAdapter adapter = new SimpleAdapter(
getActivity(), leadlist,R.layout.leadlistview, new String[] { Tag_Lead},
new int[] { R.id.textView6});
// updating listview
setListAdapter(adapter);
//get leads of order
ListView lv=getListView();
lv.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1,
int arg2, long arg3) {
// TODO Auto-generated method stub
String pid=((TextView) arg1.findViewById(R.id.textView6)).getText().toString();
LeadDetail frag=new LeadDetail();
Bundle bnd=new Bundle();
bnd.putString("lead",pid);
frag.setArguments(bnd);
FragmentManager fm=getFragmentManager();
FragmentTransaction ft=fm.beginTransaction();
ft.replace(R.id.content_frame, frag);
ft.addToBackStack(null);
ft.commit();
}
});
}
else {
String e="Lead Not Found";
ItemNotFound frag=new ItemNotFound();
//Frag1 frag=new Frag1();
Bundle bnd=new Bundle();
bnd.putString("data",e);
frag.setArguments(bnd);
FragmentManager fm1=getFragmentManager();
FragmentTransaction ft1=fm1.beginTransaction();
ft1.replace(R.id.content_frame, frag,st);
ft1.addToBackStack(st);
ft1.commit();
}
}
Code for ItemNotFound.............
public class ItemNotFound extends SherlockFragment{
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
super.onCreate(savedInstanceState);
View V = inflater.inflate(R.layout.itemnotfound, container, false);
TextView tv=(TextView)V.findViewById(R.id.textView7);
Bundle bnd=this.getArguments();
String s=bnd.getString("data");
tv.setText(s);
return V;
}
}
You can see my solution here.
I have a ViewPager with three pages which contains Fragments. In first page, I have a ListFragment and onListItemClick I replace that Fragment with another one. When Back Button is pressed, I go back to ListFragment.
Related
As the title says when on the "Home Fragment" when i click on an image tile I want the new activity to load but I would like to keep the navbar visible. Currently with the code below the activity starts but the navbar disappears. I would like help to write code so the activity starts but the navbar stays.
public class HomeFragment extends Fragment {
private ImageView imageCbt;
private ImageView imageDistorted;
#Nullable
#Override
public android.view.View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_home, container, false);
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);
// get the button view
imageCbt = getView().findViewById(R.id.whatIsCbt);
imageDistorted = getView().findViewById(R.id.distortedThinking);
// set a onclick listener for when the button gets clicked
imageCbt.setOnClickListener(new View.OnClickListener() {
// Start new list activity
public void onClick(View v) {
Intent mainIntent = new Intent(getActivity(),
IntroActivity2.class);
startActivity(mainIntent);
}
});
imageDistorted.setOnClickListener(new View.OnClickListener() {
// Start new list activity
public void onClick(View v) {
Intent mainIntent = new Intent(getActivity(),
TwelveTypesDistortedThinkingActivity.class);
startActivity(mainIntent);
}
});
}
To change the current fragment, you can replace the code inside your click listeners to this one (Replacing a fragment with another fragment inside activity group):
Fragment newFragment = new ExampleFragment();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack if needed
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();
Then you need to convert your activities to Fragment (maybe some refactoring will be necessary) and to change the current fragment in the onClickListener methods.
PS: When you use a navbar, fragments are a best practice in application architecture.
The ListView inside of a Fragment that contains a ViewPager is empty when I return back to it. This ViewPager is inside of a Fragment because I'm using a Navigation Drawer Layout. I'll try to explain it in more details now:
I am using a Navigation Drawer layout and, consequently, using Fragments. In the main activity, in onCreate, I set the current Fragment with these lines of code:
#Override
protected void onCreate(Bundle savedInstanceState) {
/* More code */
currentFragment = new MainFragment();
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().replace(R.id.layout_for_fragments, currentFragment).commit();
}
The MainFragment class contains a ViewPager that is initialized with these lines of code in the onCreateView():
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
/* More code */
ViewPager viewPager = (ViewPager) rootView.findViewById(R.id.main_view_pager);
viewPager.setAdapter(new SimpleFragmentPagerAdapter(getActivity(), getActivity().getSupportFragmentManager()));
/* Code for Tablayout */
return rootView;
}
One of the Fragments of the SimpleFragmentPagerAdapter class is this one that implements LoaderManager.LoaderCallbacks
public class ExpensesFragment extends Fragment implements LoaderManager.LoaderCallbacks<Cursor> {
private ExpenseCursorAdapter mExpenseCursorAdapter;
private static final int EXPENSE_LOADER = 1;
public ExpensesFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_expenses, container, false);
ListView expensesListView = (ListView) rootView.findViewById(R.id.expenses_list_view);
mExpenseCursorAdapter = new ExpenseCursorAdapter(getContext(), null);
expensesListView.setAdapter(mExpenseCursorAdapter);
getLoaderManager().initLoader(EXPENSE_LOADER, null, this);
return rootView;
}
#Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
return new CursorLoader(/* arguments */);
}
#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
mExpenseCursorAdapter.swapCursor(data);
}
#Override
public void onLoaderReset(Loader<Cursor> loader) {
mExpenseCursorAdapter.swapCursor(null);
}
}
On the first run, everything works fine. However, if I click on the navigation drawer menu, which I'm implementing this way, the ListView becomes empty:
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
int id = item.getItemId();
if (id == R.id.nav_main) {
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().remove(currentFragment).commit();
currentFragment = new MainFragment();
fragmentManager.beginTransaction().replace(R.id.layout_for_fragments, currentFragment).commit();
} else if (id == R.id.nav_blank) {
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().remove(currentFragment).commit();
currentFragment = new BlankFragment();
fragmentManager.beginTransaction().replace(R.id.layout_for_fragments, currentFragment).commit();
}
drawer.closeDrawer(GravityCompat.START);
return true;
}
The problem also exists when I rotate the device. There is a difference though. When I use the Navigation Drawer menu, none of the methods of the LoaderManager.LoaderCallbacks are called, but when I rotate the device, onLoadFinished is called.
Anyway, the problem persists. Any ideias how to solve it?
Thanks in advance.
I have found the solution!
Basically, I made two mistakes.
The first one is about the rotation of the device.
When the device is rotated, the Activity is destroyed and onCreate is called again. In this case, I should't call new MainFragment(). So, I check if the savedInstanceState is null before I call it, like this:
if (savedInstanceState == null) {
currentFragment = new MainFragment();
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction().
replace(R.id.layout_for_fragments, currentFragment).commit();
}
The second one is about a fragment within a fragment. In this case, I can't simply call getSupportFragmentManager(). I should call getChildFragmentManager() instead and that's it!
I tried to make an application that shows a fragment at start then you can change that fragment to an other one with a button in the first fragment. But when I put the button action in the fragments java, it won't start and I get the nullpointerexception error. Could you tell me why?
public class Fragment_main extends Fragment {
FragmentManager fm = getFragmentManager();
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Button button_inditas = (Button) getView().findViewById(R.id.button_inditas);
button_inditas.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
fm.beginTransaction().replace(R.id.content_frame, new Fragment_1()).commit();
}
});
return inflater.inflate(R.layout.fragment_main,container,false);
}
}
But when I put the button action in the fragments java, it won't start and I get the nullpointerexception error. Could you tell me why?
Well I see some errors on your code...
First of all you can't call getView() if you haven't inflated one, it means that you MUST inflate a view as i'll put on my answer and then you can avoid the getView() and use that view itself.
And instead of returning the inflater you have to return your View
This is how your Fragment should look like:
public class Fragment_main extends Fragment {
public Fragment_main() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main,container,false);
Button button_inditas = (Button)rootView.findViewById(R.id.button_inditas);
button_inditas.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
FragmentManager fragmentManager = getFragmentManager ();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction ();
fragmentTransaction.add (R.id.content_frame, new Fragment_1());
fragmentTransaction.commit ();
});
return rootView;
}
}
You have to inflate the view first and use the view returned by that instead of getView ().
View view = inflater.inflate (...);
and then
... = (Button) view.findView(...);
This happens because the view that is returned by getView () hasn't been created yet, so getView() returns null.
I have two fragment, "A" and "B".
When I return (BackPressed) to my fragment "A", the values of edittext aren't refresh. Why?
I have this code to call fragment "B".
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_container_pedido_novo,
container, false);
btnAddProduto = (Button) view.findViewById(R.id.btnNovoProduto);
btnAddProduto.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Fragment fragment = new FragmentContainerProduto(true);
FragmentManager frgManager = getActivity()
.getSupportFragmentManager();
frgManager.beginTransaction()
.replace(R.id.content_frame, fragment)
.addToBackStack(null).commit();
}
});
edtCodPedido = (EditText) view.findViewById(R.id.edtCodPedidoNovo);
edtVlBruto = (EditText) view.findViewById(R.id.edtVlBrutoPedidoNovo);
edtCodPedido
.setText(String.valueOf(GlobalUtil.objPedido.getCodPedido()));
edtVlBruto.setText(String.valueOf(GlobalUtil.objPedido.getVlBruto()));
return view;
}
Someone?
When you return to a fragment from the back stack Android does not re-create the fragment but re-uses the same instance of it and starts with onCreateView() in the fragment lifecycle. The key thing is you should not inflate view again in onCreateView() of the fragment to which you return, because you are using the existing fragment instance. You need to save and reuse the rootView. See here the answer of Vince Yuan How can I maintain fragment state when added to the back stack?.
Well, I just need put this code...
#Override
public void onResume() {
super.onResume();
edtVlBruto.setText(String.valueOf(GlobalUtil.objPedido.getVlBruto()));
edtCodPedido
.setText(String.valueOf(GlobalUtil.objPedido.getCodPedido()));
}
I want to remove a fragment and show a toast when I click a textView. My code shows the toast, but doesn't remove the fragment.
My method:
public void hide(View view) {
My_frag myFrag= new My_frag();
FragmentTransaction transaction = getSupportFragmentManager()
.beginTransaction();
transaction.remove(myFrag);
transaction.commit();
Toast.makeText(getApplicationContext(), "Hello", Toast.LENGTH_LONG)
.show();
}
My_frag class:
public class My_frag extends android.support.v4.app.Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.my_frag_layout, container, false);
}
}
At some point you must create and add the Fragment correct? You are re-creating the fragment in your hide(...) method so you are trying to remove something that has never been added. Sure you may have added an instance, but not the instance you are trying to remove.
Instead, create a global variable Fragment fragToRemove in your Activity. When you create the fragment (that is where ever you do transaction.add(fragToRemove = new My_Frag);) you will hold an instance. then change your transaction.remove(myFrag) to transaction.remove(fragToRemove) and it should work just fine.
Take the instance of Fragment Transaction other than that was taken while adding fragment to activity and call remove method on that and pass the same instance of Fragment which was used at the time.
Example:
public class MainActivity extends AppCompatActivity {
FragmentTransaction fragmentTransaction;
BlankFragment blankFragment;
Button b;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
b = (Button) findViewById(R.id.activity_button);
fragmentTransaction = getSupportFragmentManager().beginTransaction();
blankFragment=new BlankFragment(); //Fragment instance
fragmentTransaction.add(R.id.main_layout,blankFragment).commit();
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.remove(blankFragment).commit(); //created different
}
});
}
In the same way you can do in fragments also and can also remove fragment X on the click of component of fragment X.