Android: optimizing fragment transitions - java

So in my app I have a bunch of fragments that the user navigates through. And there are a lot of methods in my activity class that are used for fragment transitions. These are very similar to each other with the only difference being the class of the newFragment. Here is one these methods:
public void onHelpSelected() {
slideInRight();
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
HelpFragment newFragment = new HelpFragment();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);
transaction.commit();
slideOutLeft();
}
}, 500);
}
Then, I also have a few classes that describe each fragment. These are also very similar to each other: they differ only by the amount of buttons and by what these buttons do (but most of the buttons are used for fragment transitions). Here is one of these classes:
public class AuthFragment extends Fragment {
Button authRegButton;
Button authHelpButton;
OnHelpButtonListener helpCallback;
OnRegButtonListener regCallback;
#Override
public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_auth, container, false);
authHelpButton = (Button) view.findViewById(R.id.auth_help_button);
View.OnClickListener authHelpListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
helpCallback.onHelpSelected();
}
};
authHelpButton.setOnClickListener(authHelpListener);
authRegButton = (Button) view.findViewById(R.id.auth_reg_button);
View.OnClickListener authRegListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
regCallback.onRegSelected();
}
};
authRegButton.setOnClickListener(authRegListener);
return view;
}
public interface OnHelpButtonListener {
void onHelpSelected();
}
public interface OnRegButtonListener {
void onRegSelected();
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
try {
helpCallback = (OnHelpButtonListener) context;
} catch (ClassCastException e) {
throw new ClassCastException(context.toString()
+ " must implement OnHelpButtonListener");
}
try {
regCallback = (OnRegButtonListener) context;
} catch (ClassCastException e) {
throw new ClassCastException(context.toString()
+ " must implement OnRegButtonListener");
}
}
}
So, I have many pieces of code that are very similar. I bet there is a way to make all this code look much nicer and work more efficiently.
Thus, my question is how do I do that? :)
Thanks!

Here is how I solved this problem, if someone ever needs this :)
So I made an abstract class for my fragments and worked out all the code there:
public abstract class LoginFragment extends Fragment {
MediaPlayer clickPlayer;
int layoutId;
View view;
OnButtonListener buttonCallback;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
view = inflater.inflate(layoutId, container, false);
return view;
}
public interface OnButtonListener {
void onButtonSelected(LoginFragment fragment);
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
try {
buttonCallback = (OnButtonListener) context;
} catch (ClassCastException e) {
throw new ClassCastException(context.toString()
+ " must implement OnButtonListener");
}
}
public MyButton setUpButton(int buttonId) {
final MyButton button = (MyButton) view.findViewById(buttonId);
View.OnClickListener authHelpListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
clickPlayer = MediaPlayer.create(getContext(), R.raw.click);
clickPlayer.start();
LoginFragment newFragment = determineFragment(button);
buttonCallback.onButtonSelected(newFragment);
}
};
button.setOnClickListener(authHelpListener);
return button;
}
public LoginFragment determineFragment(MyButton button) {
LoginFragment result;
int buttonId = button.getId();
switch (buttonId){
case R.id.auth_help_button:
result = new HelpFragment();
break;
case R.id.agr_cancel_button:case R.id.help_cancel_button:
case R.id.reg_cancel_button:case R.id.reg_cont_cancel_button:
result = new AuthFragment();
break;
case R.id.agr_back_button:case R.id.reg_cont_button:
result = new RegContFragment();
break;
case R.id.reg_cont_agr_button:
result = new AgrFragment();
break;
case R.id.auth_reg_button:
result = new RegFragment();
break;
default:
result = null;
break;
}
return result;
}

Related

Navigates to second fragment again by pressing back button previous data exists

I have two fragments and one activity (Main Activity). Now when I go from fragment 1 to fragment 2 data in fragment 2 loads from api. But when I press back button, navigates to fragment 1 and again I go from fragment 1 to fragment 2 then the previous loaded data is there for some secs and then fragment loads new data. Why it is so? I want that whenever I go to the fragment 2 it should reload again all the data (without showing the previous data for some secs first). Which method I should use?
Here is my onclick method from fragment 1 for navigating to fragment 2.
private void bind(FragmentUserInputFormBinding binding) {
binding.btnFetchOffer.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
isAllFieldChecked = validateAllFields(binding);
if (isAllFieldChecked) {
Bundle bundle = new Bundle();
bundle.putString("appid", binding.etAppId.getText().toString());
bundle.putString("uid", binding.etUserId.getText().toString());
bundle.putString("token", binding.etToken.getText().toString());
OfferWallListFragment offerWallListFragment = new OfferWallListFragment();
offerWallListFragment.setArguments(bundle);
requireActivity().getSupportFragmentManager().beginTransaction()
.replace(((ViewGroup) requireView().getParent()).getId(), offerWallListFragment,"offerListFragment")
.setReorderingAllowed(true)
.addToBackStack("offerListFragment")
.commit();
}
}
});
}
Now I have my second fragment designed as follows fragment 2.
#AndroidEntryPoint
public class OfferWallListFragment extends BaseFragment<FragmentOfferWallListBinding> {
private RecyclerViewAdapter recyclerViewAdapter;
private int currentPage = FIRST_PAGE;
public OfferWallListFragment() {
// Required empty public constructor
}
#Override
public void onViewCreated(#NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Objects.requireNonNull(((AppCompatActivity) requireActivity()).getSupportActionBar()).setTitle("Offers List");
initViewModel(FragmentOfferWallListBinding.bind(view));
}
#NonNull
#Override
protected FragmentOfferWallListBinding initBinding(#NonNull LayoutInflater inflater, #Nullable ViewGroup container) {
return FragmentOfferWallListBinding.inflate(inflater, container, false);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_offer_wall_list, container, false);
}
private void initViewModel(FragmentOfferWallListBinding binding) {
OfferWallViewModel offerWallViewModel = new ViewModelProvider(this).get(OfferWallViewModel.class);
offerWallViewModel.getLiveData(currentPage).observe(getViewLifecycleOwner(), new Observer<OfferResponse>() {
#Override
public void onChanged(OfferResponse offerResponse) {
if (offerResponse != null) {
recyclerViewAdapter = new RecyclerViewAdapter();
recyclerViewAdapter.setOfferResponse(offerResponse);
binding.rvOfferData.setHasFixedSize(true);
binding.rvOfferData.setLayoutManager(new LinearLayoutManager(getContext()));
binding.rvOfferData.setAdapter(recyclerViewAdapter);
binding.rvOfferData.setVisibility(View.VISIBLE);
}
RecyclerViewPaginator recyclerViewPaginator = new RecyclerViewPaginator(binding.rvOfferData) {
#Override
public boolean isLastPage() {
return currentPage == offerResponse.getPages();
}
#Override
public void loadMore(int _currentPage) {
currentPage = _currentPage;
offerWallViewModel.getLiveData(Math.toIntExact(_currentPage));
}
};
binding.rvOfferData.addOnScrollListener(recyclerViewPaginator);
}
});
offerWallViewModel.getNetworkStateMutableLiveData().observe(getViewLifecycleOwner(), new Observer<NetworkState>() {
#Override
public void onChanged(NetworkState networkState) {
if (networkState == NetworkState.Companion.getLOADING()) {
binding.pbLoadingItems.setVisibility(View.VISIBLE);
} else if (networkState == NetworkState.Companion.getERROR()) {
Toast.makeText(getContext(), "Something went wrong, please check the parameters are filled perfectly", Toast.LENGTH_SHORT).show();
if (!CheckInternetConnection.isInternetAvailable(getContext())) {
Toast.makeText(getContext(), "No Internet Connection Available", Toast.LENGTH_SHORT).show();
binding.txtNoConnection.setText("No Internet Connection Available");
binding.txtNoConnection.setVisibility(View.VISIBLE);
}
binding.pbLoadingItems.setVisibility(View.GONE);
} else {
binding.pbLoadingItems.setVisibility(View.GONE);
}
}
});
}
}
Also I have handled onBackPressed method from MainActivity as follows.
#AndroidEntryPoint
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityMainBinding binding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
NavHostFragment navHostFragment = (NavHostFragment) getSupportFragmentManager().findFragmentById(R.id.fragmentContainerView);
if (navHostFragment != null) {
NavController navController = navHostFragment.getNavController();
AppBarConfiguration appBarConfiguration = new AppBarConfiguration.Builder(
R.id.userInputFormFragment, R.id.offerWallListFragment
).build();
NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);
}
}
#Override
public void onBackPressed(){
int count = getSupportFragmentManager().getBackStackEntryCount();
if(count == 0) {
super.onBackPressed();
} else {
getSupportFragmentManager().popBackStack();
}
}
}
Please have a look on it ?

Why my bottomsheetdialog interface is null [duplicate]

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 4 years ago.
E/UncaughtException: java.lang.NullPointerException: Attempt to invoke interface method 'void mm.com..fragment.BottomSheetFragment$BottomSheetListener.onButtonClicked(java.lang.String)' on a null object reference
at mm.com.blueplanet.videoclip.fragment.BottomSheetFragment$1.onClick(BottomSheetFragment.java:40)
at android.view.View.performClick(View.java:5647)
This is RecycervieAdapter class
((ItemViewHolder) holder).cmtText.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
FragmentTransaction ft = ((DetailActivity) mContext).getSupportFragmentManager()
.beginTransaction();
BottomSheetFragment bottomsheet= new BottomSheetFragment();
bottomsheet.show( ft, "BottomSheet");
}
});
This is bottomsheet
public class BottomSheetFragment extends BottomSheetDialogFragment {
Context mContext;
public BottomSheetListener mListener;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.custom_bottom_dialog, container, false);
mContext = getActivity();
ImageButton btn = (ImageButton) v.findViewById(R.id.cmt_btn);
final EditText edt = (EditText) v.findViewById(R.id.edt_cmt);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mListener.onButtonClicked("" + edt.getText().toString());
dismiss();
}
});
return v;
}
public interface BottomSheetListener {
void onButtonClicked(String text);
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
try {
mListener = (BottomSheetListener) mContext;
} catch (ClassCastException e) {
throw new ClassCastException(context.toString());
}
}
}
((ItemViewHolder) holder).cmtText.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
FragmentTransaction ft = ((DetailActivity) mContext).getSupportFragmentManager()
.beginTransaction();
BottomSheetFragment bottomsheet= new BottomSheetFragment();
bottomsheet.show( ft, "BottomSheet");
bottomsheet.onButtonClicked()
}
});
you must Implement onButtonClicked when you created new Object
and You can Edit Your Listener like this
private onItemsClicked mListener = null;
and create Two Interface
public void setOnClickListener(onItemsSelected onClickListener)
{
mListener = onClickListener;
}
public interface onItemsSelected
{
void onclick(float x, float y, String value);
}
Now You Can use it Like this
view.setOnClickListener(new LineChart.onItemsSelected() {
#Override
public void onclick(float x, float y , String value) {}

Reset RecyclerView adapter from another Fragment

I have a Fragment that contains a RecyclerView. I am trying to implement a filter on the RecyclerView. The filter UI opens a new Fragment Dialog where the user will input a value. Once the user hits the Search Button in the Fragment Dialog, the value should be returned to the RecyclerView Fragment and the existing data in the view should be cleared. I want to re-populate the RecyclerView with the new set of data that I will obtain from the server. My problem is that, I have a method called resetAdapterDetails() in the RecyclerView Fragment which works as expected if called from the RecyclerView Fragment itself. But, when I try to call the same method from the Fragment Dialog, I get an exception:
transactionList.clear(); --> is trying to clear a list which is null
Though the data is still visible in the RecyclerView.
The RecyclerView Fragment:
public class TransactionHistoryFragment extends Fragment implements SearchView.OnQueryTextListener, DateRangePickerFragment.OnDateRangeSelectedListener{
private RecyclerView recyclerview;
private TransactionHistoryAdapter adapter;
private List<Transaction> transactionList;
public TransactionHistoryFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_transaction_history, container, false);
recyclerview = (RecyclerView) view.findViewById(R.id.recyclerview);
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
recyclerview.setLayoutManager(layoutManager);
return view;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
setHasOptionsMenu(true);
getTransactionHistory("");
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.transactions_history_menu, menu);
final MenuItem searchItem = menu.findItem(R.id.action_search);
final SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
searchView.setOnQueryTextListener(this);
super.onCreateOptionsMenu(menu, inflater);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.filter_date:
FragmentManager fmDate = getActivity().getFragmentManager();
DateRangePickerFragment dialogFragmentDate = DateRangePickerFragment.newInstance(this, true);
dialogFragmentDate.show(fmDate, "Sample Fragment");
return true;
case R.id.filter_mobile:
FragmentManager fmMobile = getActivity().getFragmentManager();
SearchMobileFragment dialogFragmentMobile = new SearchMobileFragment ();
dialogFragmentMobile.show(fmMobile, "Sample Fragment");
//resetAdapterDetails();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
#Override
public boolean onQueryTextChange(String newText) {
final List<Transaction> filteredModelList = filter(transactionList, newText);
adapter.setFilter(filteredModelList);
return true;
}
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
//for filtering the list
private List<Transaction> filter(List<Transaction> models, String query) {
query = query.toLowerCase();final List<Transaction> filteredModelList = new ArrayList<>();
for (Transaction model : models) {
final String text = model.getTxnStatus().toLowerCase();
if (text.contains(query)) {
filteredModelList.add(model);
}
}
return filteredModelList;
}
//for populating the list
private void getTransactionHistory(String agentId){
GetTransactionHistoryTask task = new GetTransactionHistoryTask("agent1", "password");
task.getTransactionsByAgent("OU23","OU230000000123456789").subscribe(transactionHistoryResponse -> {
if(transactionHistoryResponse != null && transactionHistoryResponse.getTransactions() != null && transactionHistoryResponse.getTransactions().size() > 0 && transactionHistoryResponse.getErrors().size() == 0){
transactionList = transactionHistoryResponse.getTransactions();
adapter = new TransactionHistoryAdapter(transactionList);
recyclerview.addItemDecoration(new DividerItemDecoration(getActivity(), LinearLayoutManager.VERTICAL));
recyclerview.setAdapter(adapter);
onClickListnerRecyclerView();
}
else{
}
}, e -> e.printStackTrace());
}
private void onClickListnerRecyclerView() {
recyclerview.addOnItemTouchListener(
new RecyclerItemClickListener(getActivity(), new RecyclerItemClickListener.OnItemClickListener() {
#Override
public void onItemClick(View view, int position) {
try {
final Transaction transactionModel= (Transaction) adapter.getObjectAt(position);
Intent i = new Intent(getActivity(), TransactionDetailsActivity.class);
i.putExtra("transaction_object",transactionModel);
startActivity(i);
}
catch (Exception e){
Log.e("List issue", e.toString());
}
}
})
);
}
#Override
public void onDateRangeSelected(int startDay, int startMonth, int startYear, int endDay, int endMonth, int endYear) {
}
public void fetchDateRange(String startDate, String endDate) {
Log.e("DateRange",startDate + "\n" + endDate);
}
public void fetchMobileNumber(String mobileNumber) {
Log.e("Mobile",mobileNumber);
resetAdapterDetails();
}
public boolean resetAdapterDetails(){
try {
transactionList.clear();
adapter.notifyDataSetChanged();
recyclerview.setAdapter(adapter);
} catch (Exception e) {
Log.e("Reset Error", ""+e.getMessage());
}
return true;
}
}
The Dialog Fragment:
public class SearchMobileFragment extends DialogFragment {
EditText mMobileNumberEditText;
Button search_button;
public SearchMobileFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_search_mobile, container, false);
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mMobileNumberEditText = (EditText) view.findViewById(R.id.mobile_number_editText);
search_button = (Button) view.findViewById(R.id.search_button);
search_button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
dismiss();
TransactionHistoryFragment obj = new TransactionHistoryFragment();
obj.fetchMobileNumber(mMobileNumberEditText.getText().toString());
}
});
}
}
The fetchMobileNumber() method in the TransactionHistoryFragment (RecyclerView Fragment) is called through the fetchMobileNumber() method which is called from the SearchMobileFragment (Dialog Fragment).
Where am I going wrong? Why the transactionList.clear(); is throwing the null pointer exception?
You are getting the issue because you are creating new TransactionHistoryFragment instance search_button click in SearchMobileFragment. Which makes it's all variables null and initialize it again and here your transactionList becomes null.
You can achieve the same thing easily with different way also. As the place of SearchMobileFragment as a DialogFragment you can make it as Activity and start it as startActivityForResult from your TransactionHistoryFragment and implement onActivityResult callback to doing the fiteration.
But right now in your case you can manage it in different ways also:
First way:
As you are doing in your DialogFragment
search_button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
dismiss();
/*TransactionHistoryFragment obj = new TransactionHistoryFragment();
obj.fetchMobileNumber(mMobileNumberEditText.getText().toString());*/
}
});
Don't do the call for fetchMobileNumber here, in onResume of your TransactionHistoryFragment you should make a call for this. On the click of search_button save the filter data to SharedPreferences and use that in onResume of the TransactionHistoryFragment for filtering and after that clear this saved data from SharedPreferences onPause of this fragment.
You should remove
transactionList.clear();
of code from resetAdapterDetails() in TransactionHistoryFragment, because after search filter you will get updated transactionList which is already passed to adapter then forcefully no need to clear it. Or have a check before clearing it like:
if(transactionList!=null){
transactionList.clear();
}
Second way: Using BroadcastReceiver you can achieve the same thing.
Register a receiver in your TransactionHistoryFragment and sendBroadcast from SearchMobileFragment. In onReceive of the TransactionHistoryFragment do the filtration process.
I had resolved the above issue in a different way. In the Dialog Fragment I have implemented a View.OnClickListener and have created an Interface to initialize the same from the RecyclerView Fragment. I am posting the complete source codes below; the SearchMobileFragment now looks like:
public class SearchMobileFragment extends DialogFragment implements View.OnClickListener{
private OnMobileNumberSelectedListener onMobileNumberSelectedListener;
EditText mMobileNumberEditText;
Button mSearchButton;
public SearchMobileFragment() {
// Required empty public constructor
}
public static SearchMobileFragment newInstance(OnMobileNumberSelectedListener callback) {
SearchMobileFragment searchMobileFragment = new SearchMobileFragment();
searchMobileFragment.initialize(callback);
return searchMobileFragment;
}
public void initialize(OnMobileNumberSelectedListener callback) {
onMobileNumberSelectedListener = callback;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_search_mobile, container, false);
getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
mMobileNumberEditText = (EditText) root.findViewById(R.id.mobile_number_editText);
mSearchButton = (Button) root.findViewById(R.id.search_button);
mSearchButton.setOnClickListener(this);
return root;
}
#Override
public void onStart() {
super.onStart();
if (getDialog() == null)
return;
getDialog().getWindow().setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.WRAP_CONTENT);
}
public void setOnMobileNumberSelectedListener(OnMobileNumberSelectedListener callback) {
this.onMobileNumberSelectedListener = callback;
}
#Override
public void onClick(View v) {
dismiss();
onMobileNumberSelectedListener.onMobileNumberSelected(mMobileNumberEditText.getText().toString());
}
public interface OnMobileNumberSelectedListener {
void onMobileNumberSelected(String mobileNumber);
}
}
The RecyclerView Fragment modifications:
public class TransactionHistoryFragment extends Fragment implements SearchView.OnQueryTextListener,
DateRangePickerFragment.OnDateRangeSelectedListener, SearchMobileFragment.OnMobileNumberSelectedListener{
private RecyclerView recyclerview;
private TransactionHistoryAdapter adapter;
private List<Transaction> transactionList;
SearchView search;
public static final String TIMERANGEPICKER_TAG = "timerangepicker";
public TransactionHistoryFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_transaction_history, container, false);
recyclerview = (RecyclerView) view.findViewById(R.id.recyclerview);
LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity());
recyclerview.setLayoutManager(layoutManager);
return view;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
setHasOptionsMenu(true);
getTransactionHistory();
}
#Override
public void onResume() {
Log.e("onResumeTHF","invoked");
super.onResume();
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.transactions_history_menu, menu);
search = (SearchView) menu.findItem(R.id.action_search).getActionView();
search.setOnQueryTextListener(this);
super.onCreateOptionsMenu(menu, inflater);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.filter_date:
FragmentManager fmDate = getActivity().getFragmentManager();
DateRangePickerFragment dialogFragmentDate = DateRangePickerFragment.newInstance(this, true);
dialogFragmentDate.show(fmDate, "Sample Fragment");
return true;
case R.id.filter_mobile:
FragmentManager fmMobile = getActivity().getFragmentManager();
SearchMobileFragment dialogFragmentMobile = SearchMobileFragment.newInstance(this);
dialogFragmentMobile.show(fmMobile, "Sample Fragment");
return true;
default:
return super.onOptionsItemSelected(item);
}
}
#Override
public boolean onQueryTextChange(String newText) {
Log.e("newText",newText);
final List<Transaction> filteredModelList = filter(transactionList, newText);
adapter.setFilter(filteredModelList);
return true;
}
#Override
public boolean onQueryTextSubmit(String query) {
return false;
}
#Override
public void onMobileNumberSelected(String mobileNumber) {
Log.e("mobileNumber",mobileNumber);
resetAdapterDetails();
}
public boolean resetAdapterDetails(){
try {
transactionList.clear();
adapter.notifyDataSetChanged();
recyclerview.setAdapter(adapter);
} catch (Exception e) {
Log.e("Reset Error", ""+e.getMessage());
}
return true;
}
}
Happy coding!
The null pointer exception is because when you create a new TransactionHistoryFragment using new onViewCreated is not called and hence transactionList is never initialized. You can create a setter for the list or pass it as a constructor to the fragment to fix this

How to switch between fragments using buttons

Fragment 1:
public class homePage extends Fragment {
private OnFragmentInteractionListener mListener;
private View view;
public homePage() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_home_page, container, false);
Button btnLogin = (Button) view.findViewById(R.id.login);
Button btnRegister = (Button) view.findViewById(R.id.register);
btnLogin.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
loginView();
}
});
btnLogin.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
registerView();
}
});
return view;
}
public static homePage newInstance() {
homePage fragment = new homePage();
Bundle args = new Bundle();
return fragment;
}
public void registerView(){}
public void loginView(){}
public interface OnFragmentInteractionListener {
}
}
Acitivty :
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
homePage homepage = new homePage();
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, homepage)
.commit();
}
}
}
My fragment1 has two buttons with the id's "login" and "register". Whenever login is clicked, I want to go to my fragment_login.xml, and when register is clicked I want to go to my fragment_register.xml. Should I create these functions in my activity or in my fragment? And how should I do this? I'm fairly new to android and I'm trying to learn these basic things atm. Thanks for the help :(
Login context: "com.example.hoofdgebruiker.winkelskortrijk.login"
Register context: "com.example.hoofdgebruiker.winkelskortrijk.register"
You have to make a communication between Fragment objects via an Interface.
The Activity that make the switch between your fragments needs to implement that Interface.
So, in your case your classes must be defined as follows. This is your Interface, it helps you to tell your activity that a button has been clicked from within your Fragment:
public interface HomeClickListener {
void onLoginClick();
void onRegisterClick();
}
Your Activity needs to implement the above interface in order to be notified when a button has been clicked:
public class HomeActivity extends Activity implements HomeClickListener {
void onLoginClick() {
// Your activity code to replace your current Fragment with your Login fragment
}
void onRegisterClick() {
// Your activity code to replace your current Fragment with your Register fragment
}
}
Your fragment is hosted by an Activity, so you need to have a reference to it and notify it via an Interface:
public class LoginFragment extends Fragment {
final HomeClickListener homeClickListener
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// This makes sure that the container activity has implemented
// the callback interface. If not, it throws an exception
try {
homeClickListener = (homeClickListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString() + " must implement OnHeadlineSelectedListener");
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_home_page, container, false);
Button btnLogin = (Button) view.findViewById(R.id.login);
Button btnRegister = (Button) view.findViewById(R.id.register);
btnLogin.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
homeClickListener.onLoginClick();
}
});
btnLogin.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
homeClickListener.onRegisterClick();
}
});
return view;
}
}
More information here.

android fragment version 4 text issue

I wrote android code using fragments (Im a newbe) and i want when fragments switched to put some text in the text view. my fragments are making the switch (like intent) but theange text doesn't change. here is the code:
public class Map_Frag extends Fragment {
---interface---
Communicator callback;
TextView tv;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.frag_map, container, false);
tv = (TextView)v.findViewById(R.id.textView);
return v;
}
#Override
public void onStart() {
super.onStart();
Bundle bundle = getArguments();
if (bundle != null) {
if (bundle.getBoolean("str1"))
changTextToWalla1("str1",bundle.getInt("x"));
}
}
public void changTextToWalla1(String str1, int x) {
switch (x){
case 1:
tv.setText("number one");
break;
case 2:
tv.setText("number two");
break;
}
}
}
/*
if (bundle != null) {
if (bundle.getBoolean("button1"))
changTextToWalla1("Selected", bundle.getInt("num"));
}
}
---control class--
public class Control_Frag extends Fragment {
Communicator callback;
private Button button1;
private Button button2;
#Nullable
#Override
public void onAttach(Context context){
super.onAttach(context);
callback= (Communicator) context;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.frag_control,container,false);
button1 = (Button)v.findViewById(R.id.button_1);
button2 = (Button)v.findViewById(R.id.button_2);
button1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
callback.button1Clicked("button1", 1);
}
});
button2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
callback.button2clicked("button2", 2);
}
});
return v;
}
----communicator---
public interface Communicator {
//here i write the functions that im going to use in the project -
//all the functions that move from one fragmant to another
public void button1Clicked (String str1,int x);
public void button2clicked (String str2,int x);
}
-----main---
public class MainActivity extends FragmentActivity implements Communicator{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (findViewById(R.id.small_device) != null) {
Control_Frag cf = new Control_Frag();
FragmentManager fm = getSupportFragmentManager();
fm.beginTransaction().add(R.id.small_device, cf , "cf").addToBackStack("cf").commit();
// In small device it will show only Control_Frag to begin with
}
}
#Override
public void button1Clicked(String str1, int x) {
//When button 1 is pressed - change text to walla 1
// Identifying Map_Frag in Fragment Manager
Map_Frag ma = (Map_Frag) getSupportFragmentManager().findFragmentById(R.id.frag_content);
// TABLET
if( ma != null){
ma.changTextToWalla1(str1 ,x);
}
else {
ma = new Map_Frag();
Bundle bundle = new Bundle();
bundle.putBoolean(str1, true);
bundle.putInt(str1 ,x);
ma.setArguments(bundle);
FragmentManager fm = getSupportFragmentManager();
fm.beginTransaction().replace(R.id.small_device,ma,"sadf").addToBackStack("sadf").commit();
}
}
#Override
public void button2clicked(String str2, int x) {
Map_Frag ma = (Map_Frag)getSupportFragmentManager().findFragmentById(R.id.frag_content);
if (ma != null) {
ma.changTextToWalla1(str2, x);
}else{
ma = new Map_Frag();
Bundle bundle = new Bundle();
bundle.putBoolean(str2, true);
bundle.putInt(str2, x);
ma.setArguments(bundle);
FragmentManager fm = getSupportFragmentManager();
fm.beginTransaction().replace(R.id.small_device,ma,"asd").addToBackStack("asd").commit();
}
}
}
I could use some help to get it done
Why don't you create a separate fragment xml with the design you want and just call the fragment when a user decides to switch between them.
public void onNavigationDrawerItemSelected(int position) {
// update the main content by replacing fragments
Fragment fragment = null;
switch (position) {
case 0:
fragment = new Fragment1();
break;
case 1:
fragment = new Fragment2();
break;
default:
break;
}
if (fragment != null) {
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.container, fragment).commit();
}
}
public void onSectionAttached(int number) {
switch (number) {
case 1:
mTitle = getString(R.string.title_section1);
break;
case 2:
mTitle = getString(R.string.title_section2);
break;
case 3:
mTitle = getString(R.string.title_section3);
break;
}
}

Categories

Resources