Android studio Can't find button ID in java file - java

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.

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

Onclick method not found in parent or ancestor context

I get an error for a very simple thing. I have created a test button and an onClick method to just change the layout. I did it in a simple way so you could understand my problem better.
This is my button method:
public void accountButton (View v){
setContentView(R.layout.activity_start);
}
And this is the xml file of my button:
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Test"
android:id="#+id/button"
android:layout_below="#+id/welcomeTxt"
android:layout_centerHorizontal="true"
android:layout_marginTop="149dp"
android:onClick="accountButton"
android:nestedScrollingEnabled="true" />
I get the following error when i click the button:
java.lang.IllegalStateException: Could not find method
accountButton(View) in a parent or ancestor Context for
android:onClick attribute defined on view class
android.support.v7.widget.AppCompatButton with id 'button'
You may be calling your setContentView method from another activity. This method inflates the layout.
If it's called outside the activity the layout belongs to, the button won't be found. The most common way to initilize an activity from another is by intent.
Intent intent = new Intent(this, StartActivity.class);
startActivity(intent);
And then, inside your activity you call setContentView(R.layout.your_activity_layout) to inflate the layout. If you do this, you can call the onClick(View view) referred in the xml file from inside your activity normally.
For those that still have issues, in Android Studio or Intellij IDE, this is likely to a cached version of the class you are using (or its predecessors), that is not being recompiled.
Do an "Invalidate Cache/restart" and your problems are likely to go away.
When I had this issue occur repeatedly, I noticed that it was due to a "File Lock", triggered by Google Drive, that was making a copy of my File(s). Temporary disabling that solved all my issues.
you should not call setContentView(R.layout.activity_start); inside onClick() mentod of button.you have to call setContentView(R.layout.activity_start); inside oncreate() method.
follow the steps to achieve it.
implement OnClickListener in your class
initialize the button in onCreate()
Button button = (Button) findViewById(R.id.button);
set the setOnClickListener() method for button
btn.setOnClickListener()
then call the method outside of oncreate()
public void accountButton (View v){ //do some thing which you want }

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

How to get information from my Android Fragment to MyActivity.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.

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