How to get information from my Android Fragment to MyActivity.java - java

I'm trying to learn to create an Android fragment to implement an amount insert box which I can reuse throughout my application. So I create a simple xml file which has some EditText boxes. I then created the associated java file called AmountFragment.java:
public class AmountFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.amount_fragment, container, false);
return view;
}
}
I then use this fragment in another xml file:
<fragment
android:name="com.example.android.ui.widget.AmountFragment"
android:id="#+id/transaction_amount"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
This works fine so far. It shows the fragment fine and I can insert numbers in it. I now want to be able to get the inserted text in the mainActivity. So I read this page on Fragments from the Android docs, but I'm totally lost. The code they show makes no sense at all to me. I need to define an interface, but I have no clue what I have to do with it. I tried simply copy-pasting it over, but I get an InflateException. Since I don't even know what's going on I have no clue where to look for a solution.
So my question: can anybody give me some pointers on how to interface this fragment with the Activity in which I use it?

Try the following code.
In MainActivity.java add
public void getMessage(Object obj) {
Log.d("My App", "Look at my object " + obj.toString();
}
That will get objects from your AmountFragment, then in your AmountFragment write:
String anyObject = "Yay something";
((MainActivity)getActivity()).getMessage(anyObject);
What's happening here is that getActivity() will get the instance of the Activity which contains the fragment, then you cast it to your activity, MainActivity, and call the receiver method you wrote for it.

Related

Implement bottom drawer in android Java

I am unable to implement a bottom drawer in android (java) and can not find any working example/tutorial on its usage. Can you write sample code for using a bottom drawer? (https://material.io/components/navigation-drawer/#bottom-drawer)
Alternatively, I tried using a drop down menu but my app needs a bottom drawer only
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/navbottom"
android:layout_width="match_parent"
android:layout_height="64dp"
android:layout_gravity="bottom"
app:menu="#menu/menu_nav"> </com.google.android.material.bottomnavigation.BottomNavigationView>```
Here's the code to my bottom navigation view
This is how it should look like1
In the screenshot that you added, I saw something that looks like BottomSheet. To get this look of dialog you probably want to use BottomSheetDialogFragment so below I will explain how to implement it inside your Activity.
1) First of all, you need to create a class that will extend from BottomSheetDialogFragment and inflate the layout that will be used by this fragment.
public class ExampleBottomSheetDialog extends BottomSheetDialogFragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle
savedInstanceState) {
return inflater.inflate(*R.layout.bottom_sheet_layout*, container, false);
}
}
2) Then you need to create the *R.layout.bottom_sheet_layout* layout file that will hold needed views and provide logic for them if it's needed.
3) After that, you can programmatically set Dialog logic. So for example, you could open this dialog by pressing the button.
Button buttonDialogBottomSheet = findViewById(R.id.btn_sh_dialog);
buttonDialogBottomSheet.setOnClickListener((v) -> {
ExampleBottomSheetDialog bottomSheetDialog = new ExampleBottomSheetDialog();
bottomSheetDialog.show(getSupportFragmentManager(), "simple tag");
});
If you're looking for standard Bottom Sheet just let me know, I will update the answer.
Result of code written above:
link

Android studio Can't find button ID in java file

I've started working on a menu for my app and I'm trying to start an activity from a fragment. My fragment code looks like this;
public class Studies extends Fragment {
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
getActivity().setTitle("Studies");
}
public void goToAttract(View v) {
Intent intent = new Intent(getActivity(), informaticainfo.class);
startActivity(intent);
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.studies, container, false);
}}
I've got this working in a different project so I do not think that is the problem, my XML button to go to the next activity looks like this;
<Button
android:id="#+id/I"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginStart="0dp"
android:layout_marginLeft="0dp"
android:layout_marginTop="40dp"
android:background="#drawable/buttonshape"
android:onClick="goToAttract" <---- is this wrong?
android:paddingLeft="130sp"
android:paddingRight="130sp"
android:text="#string/informatica"
android:textColor="#ffffff" />
I've declared the new activity in the Manifest, but the XML file keeps giving this error at the line specified above;
Cannot resolve symbol 'goToAttract' less
Inspection info: Checks if the method specified in onClick XML attribute is declared in related activity.
Does the method I'm using above not work with fragments? Why can it not find the function I have working in another project?
Check this link [How exactly does the android:onClick XML attribute differ from setOnClickListener?
According to this that with the XML above, Android will look for the onClick method only in the current Activity. This is important to remember if you are using fragments, since even if you add the XML above using a fragment, Android will not look for the onClick method in the .java file of the fragment used to add the XML.
Declaring and assigning value to onClickin XML does not work in fragment, use OnClickListener programmatically instead of using onClick in XML.

Can't use SharedPreference variables

I'm trying to save and retrieve data with SharedPreferences. Data stores and retrieved correctly, the problem is the app crashes on using this data to change a button text in a fragment
onCreateView() Function
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
SharedPreferences loadSettings = getActivity().getSharedPreferences("app_setts", Context.MODE_PRIVATE);
Button counterBtn = (Button) getActivity().findViewById(R.id.counterBtn);
int countInt = loadSettings.getInt("counter",0);
counterBtn.setText(String.valueOf(countInt));
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
return rootView;
}
So how to change the switch values using SharedPreference
*I have searched here but all gives crash
Sorry for bad english
Edit
I have found that i couldn't access the fragment component directly by onCreate() in MainActivity.java so i have to put my code in onCreateView() function
But there is a problem
The app runs and didn't crash but the value still won't change
Any idea to solve this ??
There's a couple of issues here.
The first is that you should probably move the code from your fragment's onCreateView() to onActivityCreated(), as that's when you are guaranteed that the Activity's onCreate has completed.
The second issue is that while this may work, it's poor design to have a fragment reach into and manipulate it's parent activity directly in this way.
The Android developer site has a good article about how to communicate between a fragment and it's activity via interfaces, at http://developer.android.com/training/basics/fragments/communicating.html
Personally, I prefer to decouple things even more, forego the interface, and use a message bus (e.g. Otto, EventBus, etc.) In this way, fragments are completely reusable / replaceable, and neither the activity nor the fragment need to know anything specific about each other - just which bus messages they emit / consume.
Logcat trace shows the 62nd line throws a NPE.
boolean onoffSwitch = loadSettings.getBoolean("appOnOff", false);
So, loadSettings must be null. You can print this by:
System.out.print(loadSettings);
So, you must try:
SharedPreferences loadSettings = getSharedPreferences("pref", Context.MODE_PRIVATE);
...
loadSettings.commit();
You may be try to get the shared preference value before save. First check you saving the values in shared preference..

Difference between fragment_main.xml and activity_main.xml

I'm following along with the tutorial here
https://developer.android.com/training/basics/firstapp/building-ui.html
and I'm confused as to why they say to edit fragment_main.xml instead of activity_main.xml. In the MainActivy.java file, the onCreate() method has a line that says
setContentView(R.layout.activity_main);
Why does it complain when I try to change it to
setContentView(R.layout.fragment_main);
Any pointers would be appreciated.
The activity is a container of fragments, a fragment is like an UI layer which can be added, modified or deleted in execution time. also in the activity layout you can have added "static" fragments.
There can be a lot of causes for your error if you swap the layouts, maybe your activity code tries to reference some views that are not in the fragment layout or viceversa, maybe the activity layout has references to fragments, etc... You can name your layouts as you want, but you need to set the layout that matches with your code in your activities/fragments
you have to use
setContentView(R.layout.activity_main);
in your program where as setContentView(R.layout.fragment_main); is used when you use Different Fragments in One Activity
and you getting error because there is no xml file present named fragment_main.xml in res folder.
its just name fragment_main or activity_main if you wish you can give your GF :D name also,
i.e when you add a layout file to res/layout path an entry will be maid in R.java
say you create main.xml in res/layout, and when you clean your project an entry R.layout.main
will be added to R.java its just the name whatever you give to file.
may be you getting error because that file not there or might be that file don't hold layout in it.
Both are optional. But, It's always better using one layout to avoid confusion into your code. Which in this case I will suggest using activity_main.xml and delete the fragment_activity.xml following the below procedure:
1.Creat project normally.
2.Copy fragment_main.xml to activity_main.xml (content). Then delete fragment_main.xml
3.In MainActivity.java delete the following content :
if (savedInstanceState == null) {
getFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment()).commit();
}
and
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container,
false);
return rootView;
}
}
Hope this help

Start activity in a Fragment

I've decided to add more tablet-friendly UI to my app by creating a dual-pane layout using the new fragments API. But the problem is that lots of screens in my app are Activity subclasses. Manually converting them all to fragments is not an option because:
- There are nearly 50 activities.
- I'd like my app to be compatible with all versions of Android starting at 1.6
- And I'd like it to be as small as possible so using a compatibility library is not an option as it is too huge
Although I've found some questions whose answers are saying that it is impossible, I've done it almost successfully. Here is code of my custom Fragment:
public static class ActivityFragment extends Fragment{
Intent intent;
View view;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if(intent==null){
Bundle a=getArguments();
intent=a.getParcelable("intent");
}
LocalActivityManager am=((ActivityGroup)getActivity()).getLocalActivityManager();
Window wnd=am.startActivity("intent"+intent.hashCode(), intent);
if(view==null){
view=wnd.getDecorView();
view.setLayoutParams(new FrameLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.FILL_PARENT));
}
return view;
}
public void onDestroy(){
super.onDestroy();
if(!((TabletMainActivity)getActivity()).tabs.containsValue(this)){
((ActivityGroup)getActivity()).getLocalActivityManager().destroyActivity("intent"+intent.hashCode(), true);
}
}
}
In order to work it must be used only in ActivityGroup.
Only problem is that in some activities with a ListView method onItemClick() does not get called after the activity is resumed, i.e. I click an item, another activity starts on top of current, but when I go back, items are no longer clickable.
I've finally found a solution by comparing all ListView's fields' values before and after onResume. And solution to this problem is to call the notifyDataSetInvalidated() method on the list adapter.

Categories