I have a simple block code and i wish pass this fragment to another fragment with a click in a button.
If anyone could help me I would appreciate it
#Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_inicio,container,false);
linearLayout = view.findViewById(R.id.clientea);
linearLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(getActivity(),"Teste",Toast.LENGTH_SHORT).show();
}
});
return view;
}
I will show a simple way with code.
There are one Activity and two Fragments in the code.
First , the MainActivity contains the FragmentOne.
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getSupportFragmentManager().beginTransaction().add(R.id.container, new FragmentOne(), "")
.addToBackStack(null)
.commit();
}}
Then FragmentOne, there is a button in it, which will jump FragmentTwo when click.
public class FragmentOne extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_one, container, false);
Button btnClick = view.findViewById(R.id.btn);
btnClick.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getActivity().getSupportFragmentManager().beginTransaction()
.replace(R.id.container, new FragmentTwo())
.addToBackStack(null)
.commit();
}
});
return view;
}}
The last is the FragmentTwo:
public class FragmentTwo extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_two, container, false);
return view;
}
}
I could give the xml if you want.
From my experience with Android development, the approach that is taken to this problem is to create a functional interface, implement the interface in the Activity that the fragments are managed by and then do the fragment swapping inside the method provided by the interface.
So first create an interface, let's call it IFragmentToSwap.
public interface IFragmentToSwap{
void OnButtonClicked();
}
Then in the Activity that controls fragment transactions you need to implement this interface.
public class MainActivity extends AppCompatActivity implements IFragmentToSwap {
#Override
public void OnButtonClicked()
{
//Swap fragment here
}
}
Now in your fragment in the OnAttach override method you should do the following:
private IFragmentToSwap mListener;
#Override
public void onAttach(Context context)
{
super.onAttach(context);
if (context instanceof IFragmentToSwap)
{
mListener = (MainActivity) context;
}
else
{
throw new RuntimeException(context.toString()
+ " must implement IFragmentToSwap");
}
}
And in the method you provided that is contained inside your fragment you would call the method on the functional interface when a click happens, like this:
#Override
public View onCreateView(final LayoutInflater inflater, final
ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_inicio,container,false);
linearLayout = view.findViewById(R.id.clientea);
linearLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mListener.OnButtonClicked();
Toast.makeText(getActivity(),"Teste",Toast.LENGTH_SHORT).show();
}
});
return view;
}
And don't forget to detach the listener in the OnDetach override:
public void onDetach()
{
super.onDetach();
mListener = null;
}
This is the most common approach I have seen to swapping fragments on Android.
Related
I just created my first Android app through Android Studio using Java. I am working with two fragments in the process. The first fragment consists of a gridview with cards. When you click on a card you get to the Second Fragment. So far everything works. My problem is that when returning from the Second Fragment to the First Fragment (CategoryFragment) via the AppBar, the content remains empty. It seems that the method onCreateView is not executed again. What did I do wrong? Did I not understand something correctly?
public class CategoryFragment extends Fragment implements CardViewAdapter.ItemClickListener{
private RecyclerView recyclerView;
private CategoriesService categoriesData;
private SharedPreferences sharedPreferences;
private RequestQueue queue;
private FragmentCategoryBinding binding;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
sharedPreferences = this.getActivity().getSharedPreferences("SPOTIFY", 0);
queue = Volley.newRequestQueue(this.getActivity());
Toast.makeText(this.getContext(), "categoryFragment loaded" ,Toast.LENGTH_LONG).show();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
View view = inflater.inflate(R.layout.fragment_category, container, false);
categoriesData = new CategoriesService( view.getContext(), this.queue, this.sharedPreferences);
categoriesData.loadData();
CardViewAdapter mAdapter = new CardViewAdapter(view.getContext(), categoriesData.getCategories());
mAdapter.setClickListener(this);
recyclerView = view.findViewById(R.id.categoriesGrid);
recyclerView.setLayoutManager(new GridLayoutManager(view.getContext(), 6));
recyclerView.setAdapter(mAdapter);
return view;
/*
binding = FragmentCategoryBinding.inflate(inflater, container, false);
return binding.getRoot();
*/
}
public void onViewCreated(#NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
/*
binding.buttonFirst.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
NavHostFragment.findNavController(CategoryFragment.this)
.navigate(R.id.action_FirstFragment_to_SecondFragment);
}
});
*/
}
#Override
public void onItemClick(View view, int pos) {
SpotifyCategoryCard item = categoriesData.getCategory(pos);
Toast.makeText(getContext(), "Click on '"+ item.getTitle() +"' (Type: '"+item.type+"')" ,Toast.LENGTH_SHORT).show();
NavHostFragment.findNavController(CategoryFragment.this)
.navigate(R.id.action_FirstFragment_to_SecondFragment);
}
#Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
}
I have an app with 4 tabs, all are Fragments and have an adapter because I'm using RecyclerView. On the first tab I have items. I want the second tab to show the items that are checked on the first and listen to the changes. The 3rd tab shows the items from the 2nd tab (=1st tab checked items) when I click on a button on the first segment. Now I set the listeners in onCreate and onCreateView. Sometimes it's working, sometimes not. My suspicion is that the create methods aren't executed in the same order every time. The other problem is that sometimes my Fragment has to notify the listener, sometimes the the Fragment's adapter. How do I treat it nicely?
First tab (it's adapter will notify)
public class EventFragment extends Fragment implements BettingEventAdapter.BettingItemClickListener {
private RecyclerView recyclerView;
static private BettingEventAdapter adapter;
private BettingListDatabase database;
private static Answer bettingData = null;
private static final String TAG = "EVENT";
private static BettingEventAdapter.BettingItemClickListener listener;
public static void setListener(BettingEventAdapter.BettingItemClickListener _listener) {
listener = _listener;
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
database = BettingListDatabase.getInstance(this.getContext());
loadBettingData();
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container,
#Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_events,
container, false);
recyclerView = view.findViewById(R.id.MainRecyclerView);
adapter = new BettingEventAdapter(this);
adapter.addBettingItemListener(listener);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity().getBaseContext()));
recyclerView.setAdapter(adapter);
loadItemsInBackground();
return view;
}
Second tab:
public class TicketFragment extends Fragment implements BettingEventAdapter.BettingItemClickListener {
private RecyclerView recyclerView;
TextView prizeTextView;
EditText stakeInput;
Button bSave;
private static BettingTicketAdapter.TicketSaveClickListener listener;
private BettingListDatabase database;
private BettingTicketAdapter adapter;
double odds=1;
int stake=0;
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
database = BettingListDatabase.getInstance(this.getContext());
EventFragment.setListener(this);
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_ticket,
container, false);
recyclerView = view.findViewById(R.id.TicketRecyclerView);
adapter = new BettingTicketAdapter();
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity().getBaseContext()));
recyclerView.setAdapter(adapter);
}
Third tab:
public class TicketListFragment extends Fragment implements BettingTicketAdapter.TicketSaveClickListener {
private BettingTicketListAdapter parentAdapter;
private BettingListDatabase database;
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
database = BettingListDatabase.getInstance(this.getContext());
TicketFragment.setListener(this);
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
View view = inflater.inflate(R.layout.fragment_ticket_list,
container, false);
RecyclerView parentRecyclerView = view.findViewById(R.id.SavedTicketParentRecyclerView);
parentAdapter = new BettingTicketListAdapter();
//TODO db-ből feltölteni
loadItemsInBackground();
parentRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity().getBaseContext()));
parentRecyclerView.setAdapter(parentAdapter);
return view;
}
Pager activity:
public class PagerActivity extends AppCompatActivity {
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pager);
}
#Override
protected void onResume() {
super.onResume();
ViewPager mainViewPager = findViewById(R.id.mainViewPager);
TabPagerAdapter tabPagerAdapter = new TabPagerAdapter(getSupportFragmentManager(), this);
mainViewPager.setAdapter(tabPagerAdapter);
}
}
https://developer.android.com/training/basics/fragments/communicating
To allow a Fragment to communicate up to its Activity, you can define an interface in the Fragment class and implement it within the Activity. The Fragment captures the interface implementation during its onAttach() lifecycle method and can then call the Interface methods in order to communicate with the Activity.
Here is an example for your Fragment:
EventFragment
public class EventFragment extends Fragment {
OnEventSelectedListener callback;
public void setOnEventSelectedListener(OnEventSelectedListener callback) {
this.callback = callback;
}
// This interface can be implemented by the Activity, parent Fragment,
// or a separate test implementation.
public interface OnEventSelectedListener {
public void onEventSelected(int position);
}
// ...
}
PagerActivity
public class PagerActivity extends AppCompatActivity implements EventFragment.OnEventSelectedListener{
// ...
// In order to receive event callbacks from the fragment, the activity that
// hosts it must implement the interface defined in the fragment class.
//For example, the following activity implements the interface from the above example.
public void onEventSelected(int position) {
// ...
}
#Override
public void onAttachFragment(Fragment fragment) {
if (fragment instanceof EventFragment) {
EventFragment eventFragment = (EventFragment) fragment;
eventFragment.setOnEventSelectedListener(this);
}
}
}
For example, the following method in the fragment is called when the user clicks on a list item. The fragment uses the callback interface to deliver the event to the parent activity.
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
// Send the event to the host activity
callback.onEventSelected(position);
}
The problem is that when i click in the button the first time no text is in the EditText object, in the second click it works but does not replace the frame.
I Have one activity with a container for a fragment that has a editText and a button, when click the button i replace the fragment in the container with another fragment to display the text in the edit text.
I'm following this tutorial:
https://www.youtube.com/watch?v=OLbsiE42JvE&list=PLshdtb5UWjSrOJfpFOE-u55s3SnY2EO9v&index=14
i'm in video "Android tutorial (2018) - 14 - Fragment to Fragment Communication".
The diference from this tutorial from my app is that my activity is the third in the same project, and i'm working in that activity as it was my main.
public class FinalActivity extends AppCompatActivity implements HeadLineFragment.OnMessageListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_final);
if(findViewById(R.id.final_activity_fragment)!= null) {
if (savedInstanceState != null) {
return;
}
HeadLineFragment headLineFragment = new HeadLineFragment();
getSupportFragmentManager().beginTransaction().add(R.id.final_activity_fragment, headLineFragment, null).commit();
}
}
#Override
public void onMessageSend(String message) {
ArticleFragment articleFragment = new ArticleFragment();
Bundle bundle = new Bundle();
bundle.putString("message",message);
articleFragment.setArguments(bundle);
getSupportFragmentManager().beginTransaction().replace(R.id.final_activity_fragment, articleFragment,null).addToBackStack(null).commit();
}
}
public class HeadLineFragment extends Fragment {
OnMessageListener onMessageListener;
private Button button;
private EditText editText;
public interface OnMessageListener{
public void onMessageSend(String message);
}
public HeadLineFragment(){
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view= inflater.inflate(R.layout.headline_fragment, container, false);
button = view.findViewById(R.id.bfrag);
editText = view.findViewById(R.id.editText21);
button.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view) {
String message = editText.getText().toString();
String s = editText.getText().toString();
onMessageListener.onMessageSend(message);
}
});
return view;
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
Activity activity = (Activity) context;
try {
onMessageListener = (OnMessageListener) activity;
}catch (ClassCastException e){
throw new ClassCastException(activity.toString() + " must implement OnMessageListener....");
}
}
#Override
public void onResume() {
super.onResume();
editText.setText("");
}
}
public class ArticleFragment extends Fragment {
private TextView textView;
public ArticleFragment(){}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(
R.layout.article_fragment,container, false);
textView = view.findViewById(R.id.txt_message_display);
Bundle bundle = getArguments();
String message = bundle.getString("message");
textView.setText(message);
return view;
}
}
I expect that the functionality has the same behavior as in the video of the tutorial
I eventually solved my own problem, the layout of the Activity had a fragment instead of a frame layout. By changing that the problem was solved.
i have simple project that have list view
when any one click on any item on list view
open in single window
by fragment
the problem is that i want to replace my fragment with on of this tabs fragment on this project
http://www.truiton.com/2015/06/android-tabs-example-fragments-viewpager/
i put my mainactivty class in switch case but it get to me this error
in first picture
i try to import import android.support.v4.app.Fragment
but also the same promplem
this is the clases of my project
....Main2Activity class
public class Main2Activity extends AppCompatActivity implements fragmentA.comunicatir
{
fragmentA f1;
fragmentB f2;
FragmentManager manegaer;
#Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
manegaer=getSupportFragmentManager();
f1=(fragmentA)manegaer.findFragmentById(R.id.fragment1);
f1.setcomunicatir(this);
}
#Override
public void respned(int index){
f2=(fragmentB)manegaer.findFragmentById(R.id.fragment2);
if(f2!=null&&f2.isVisible()){
f2.cahngedata(index);
}else{
Intent intent=
new Intent(this,
AnotherActivity.class);
intent.putExtra("index",index);
startActivity(intent);
}
}
}
the another classes
class fragmentA
public class fragmentA extends Fragment implements AdapterView.OnItemClickListener
{
ListView list;
comunicatir com;
#Override
public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.fragment1,container,false);
list=(ListView)view.findViewById(R.id.listView1);
ArrayAdapter adapter = ArrayAdapter.createFromResource(getActivity(),
R.array.chapters, android.R.layout.simple_list_item_1);
list.setAdapter(adapter);
list.setOnItemClickListener(this);
return view;
}
public void setcomunicatir (comunicatir comunicator)
{
this.com=comunicator;
}
#Override
public void onItemClick(AdapterView<?> adapterView, View veiw, int i, long l) {
com.respned(i);
}
public interface comunicatir
{
public void respned(int index);
}
}
public class fragmentB extends Fragment
{
TextView text;
TextView textView2;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment2, container, false);
//text = (TextView) view.findViewById(R.id.textView1);
//imgv=(ImageView) view.findViewById(R.id.imageView1);
textView2 =(TextView)view.findViewById(R.id.textView22);
return view;
}
public void cahngedata(int index)
{
/*String[] descrption =getResources().getStringArray(R.array.hadeith);
text.setText(descrption[index]);*/
String []Hadith=getResources().getStringArray(R.array.hadeith);
//imgv.setImageResource(img[index]);
textView2.setText(Hadith[index]);
//int []descrption =getResources().getIntArray(img[index]);
// imgv.setImageResource(descrption[index]);
/*text.setText(descrption[index]);
int arr[]=getResources().getIntArray(img[index]);
imgv.setImageResource(arr[index]);*/
}
}
public class AnotherActivity extends Activity
{
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.another);
Intent intent = getIntent();
int index= intent.getIntExtra("index", 0);
fragmentB f2= (fragmentB)
getFragmentManager().
findFragmentById(R.id.fragment2);
if (f2!=null)
f2.cahngedata(index);
}
}
the Another Activity class also have error in picture 2
1st issue: You just can't put an activity on a Tab, but you probably won't need the getItem() you can delete that method
2nd issue:
Replace:
fragmentB f2 = (fragmentB) ...
With:
fragment f2 = (Fragment) ...
go to the tab.class which u have problem in and change
import android.app.Fragment;
to
import android.support.v4.app.Fragment;
it will run .
I have two fragments MyFragment and MyFragment2 , an interface defined within MyFragment2.
code for MyFragment2:
public class MyFragment2 extends android.support.v4.app.Fragment implements View.OnClickListener {
public interface MyInterface2
{
public void respond(String s);
}
EditText editText;
Button sendData;
MyInterface2 comm;
View v=getView();
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
v = inflater.inflate(R.layout.my_fragment_2,container,false);
return v;
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
this.comm = (MyInterface2)getActivity();
editText = (EditText)getActivity().findViewById(R.id.text);
sendData =(Button)getActivity().findViewById(R.id.sendData);
sendData.setOnClickListener(this);
}
#Override
public void onClick(View v) {
try {
String s = editText.getText().toString();
comm.respond(s);
}
catch(Exception e)
{
Toast.makeText(getActivity(),"error:"+e,Toast.LENGTH_LONG).show();
}
}
}
I am trying to send the content of editText from MyFragment2 to the fragment MyFragment by pressing the button (Myfragment2 initially set on the main activity's view using the Java code)
The main activity's code is as follows*(my_layout is the id of layout in which I am putting the fragments)*:
public class MainActivity extends AppCompatActivity implements MyFragment2.MyInterface2 {
//String data;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MyFragment2 fragment2= new MyFragment2();
FragmentManager fManager= getSupportFragmentManager();
FragmentTransaction transaction= fManager.beginTransaction();
transaction.add(R.id.my_layout,fragment2,"MyFragment2");
transaction.commit();
}
public void respond(String s)
{
MyFragment fragment = new MyFragment();
FragmentManager fManager =getSupportFragmentManager();
FragmentTransaction transaction = fManager.beginTransaction();
transaction.replace(R.id.my_layout,fragment);
transaction.commit();
fragment.getData(s);
}
}
when I click the sendData button in fragment MyFragment2 , MyFragment2 gets replaced with fragment Myfragment but no data change occurs in the MyFragmnet's textView and an error is also shown which I have catched in a try catch block from fragment MyFragment2(here is the image for that).
code for MyFragment :
public class MyFragment extends android.support.v4.app.Fragment {
TextView textView;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v= inflater.inflate(R.layout.my_fragment,container,false);
//textView =(TextView)v.findViewById(R.id.getText);
return v;
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
textView =(TextView)getActivity().findViewById(R.id.getText);
}
public void getData(String data)
{
textView.setText(data);
}
}
You can easily pass data between fragments using a callback or passing the arguments via a bundle.
Check out this article:
https://developer.android.com/training/basics/fragments/communicating.html
onActivityCreated is no need. Uncomment ur text view initiation statement in onCreateView block.
Ensure you have text view in your respective layout file with same id you have passed