rename fragment class which is referenced in the xml - android

I love fragments - BUT renaming the classes is a real pain if the fragment class is referenced in an xml like this:
<fragment
android:id="#+id/listFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.pkg1.Screens.MyFragmentClass" >
Now when renaming MyFragmentClass with its java file renames only JAVA files - all the xml referenced stay the same.
Is there a "secret" way to rename so that also the xml references get updated?

Not particularly secret, but you could use Eclipse to do a File Search, use a file name pattern of *.xml, and replace "class="com.pkg1.Screens.MyFragmentClass"" with whatever you're renaming it to...?

Related

AndroidStudio not recognizing .java file

For some unknown reason, android studio decided not to recognize the .java file. Any idea how to resolve this?
I've tried deleting the file and recreating it, but it still results in the same issue. When recreating the file, some error came up and the file is automatically recreated
public class SubmitDealAsyncTask extends AsyncTask<Void, Void, String> {
...
}
It turns out that there's a wrong file association entry which associate that particular filename as a JavaFX file.
Look in the Preferences > Editor > File Types under Java files, the name of SubmitDealAsyncTask.java file is there and all I needed to do is to remove it.
Check your java file name and Class name.
class SubmitAsyncTask {}
should be saved in "SubmitAsyncTask.java"
Go to Preferences > Editor > File Types > Java, and then under each of the listed file types (Yes, unfortunately you have to look through all of them), and scroll down at the bottom of the to see if there is an entry for you file, and then click on it and the click the - sign.
How did you include this file? I had problems just copying java classes in Android Studio, so maybe you might want to create a new java class and copy the content of the desired file into it. Then there should be no problem.
Try to copy all the code from this file and paste it inside your package(where you paint over you name with blue lines).
Android Studio will create new .java file for you there.
#root I created the class by right clicking on the package folder(com.example.tttt) in the project view and then new java class and naming it SubmitAsyncTask and then using the prototype you provided to create a dummy class and it worked for me as you can see below so if this doesn't solve it then you are missing something in the code its no longer an IDE problem :

Data Binding class not generated

I am using Data Binding in my project, when using <layout> and <data> in my xml binding class is not generated.
For example i have activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data> </data>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
</RelativeLayout>
</layout>
Now if i am writing ActivityMainBinding in my activity/fragment it shows error that class is not available. But after including <variable> in my xml file, it is able to generate ActivityMainBinding class.
Android Studio : 2.1.3
Classpath : com.android.tools.build:gradle:2.1.3
minSdkVersion 16
targetSdkVersion 24
buildToolsVersion 24.0.0
I did not get any satisfying answers. So here are the tips which are summary of my data binding knowledge.
Tips For Solving DataBinding Issues
Update
To get more accurate errors and suggestions, I strongly recommend to update Android Studio and Gradle plugin version to the latest. Because I am not facing many issues after AS 3.2 version.
See Latest Android Studio, and Latest Gradle Plugin.
Orignal Solution
After reading this answer, you will not get stuck in data binding auto generation issues for both Classes and Data Variables.
Check these points one by one. Any of these can make your work done. Point 3 to last are really important, so don't miss them.
1. Check if data-binding enabled
You should have data binding enabled in build.gradle. If not then add this and Sync.
android {
...
buildFeatures {
dataBinding true
}
}
2. Check layout is converted in binding layout
Now if you want data binding class to be generated then you should wrap xml layout with data binding (<layout tag). Something like this.
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.constraint.ConstraintLayout>
</layout>
Along with this check whether the binding variable names are correct as in the view model class
3. Auto-generated Binding class name?
Your data binding class should be generated after creating binding layout.
If your layout name is in snake case activity_main.xml then data binding class
will be generated in camel case like ActivityMainBinding.
4. Can't See Import Suggestion?
Sometimes when you type ActivityMai..., then it does not show suggestion, in that case import manually.
import <yourpackage>databinding.ActivityMainBinding;
5. Read Build Fail Logcat
Your binding class and new variables in layout will not be generated if your build fails. So first Make project by Ctrl + F9 (Build > Make project).
If a build fails then see what is an error, usually we have errors in layout fields. Error logs will point out the error line number with the issue.
Binding may fail cause some stupid error, like syntax error or missing import. In that case, you will get logcat full of errors of binding classes. But you should read complete logcat to find appropriate issue.
6. Close and open project from recent
I always do this because it takes much less time than Rebuild / Make project.
Close project from File > Close Project
Open again from recent
Note that I prefer Close and Open from Recent because it takes much less time than Rebuild / Restart IDE.
7. Rebuild Project
If still your class is not generated. (Some time when we paste layout file, then it happens). Then Rebuild Project from Build> Rebuild (Not Build or Make project). It will generate your data binding class. (Rebuild does Magic for me.)
8. Have latest Android Studio
After updating AS to Android Studio 3.2, I felt many bugs fix in data binding auto generation. So you should also have the latest AS.
#Solution for <variables
<data>
<variable
name="item"
type="com.package.Model"/>
</data>
Usually, when we put a variable in layout, it creates a getter and setter of it. And we can use binding.setItem(item); and binding.getItem();, but if you can't see those methods then read the below information.
1. Close and open project from recent
If you have created a data variable - <variable in your layout and it does not show up its setter and getter in data binding class, then Close and Open from Recent your project.
2. Clean project after changing the type
If you changed the type of some <variable in your layout and getter setter type is not changing then Clean project (Build> Clean Project)
Final words
Finally if still your binding class is not generated, then we have our most powerful weapon. - Restart Android Studio
First, try just restart, this always generates variables of my binding layout after restart.
If it does not work then Invalidate Cache & Restart.
This is all that i do to solve my data binding errors. If you get any further issues, you can comment here.
DataBinding class generated automatically.
if your xml name is activity_test then the Binding class will be ActivityTestBinding.
but,
dataBinding {
enabled = true
}
layout should have layout as root
<layout xmlns:android="http://schemas.android.com/apk/res/android">
</layout>
I had the same issue. After reading over the android sdk docs, there is only the expected file name to be created but nothing about what to do if it does not happen. I noticed after some more research that after removing the namespace to the layout element like below (using your example), it worked for me.
<?xml version="1.0" encoding="utf-8"?>
<layout>
<data> </data>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
</RelativeLayout>
</layout>
In my case, the Binding class was generated and in place ( but I thought it wasn't) ... but it does not automatically add import of said class to the activity/fragment import section... so... OPTION + ENTER :)
dataBinding {
enabled = true
}
To enable the new data binding compiler, add the following option to your gradle.properties file:
android.databinding.enableV2=true
Update:
To enable databinding please use,
android {
...
buildFeatures {
dataBinding true
}
}
Please follow this link:
https://developer.android.com/jetpack/androidx/releases/databinding
if you do base job, for enable databainding in your project, like use enable in gradle and use layout tag in xml, when you change xml code and did not generat new databinding class for those xml you can use a fast way for generation only data binding class in gradle->other->databindinggenbaseclassesDebug it fast more than bulid whole project. its generate only databinding class.
After having set up it properly (including xml namespace and wrapping everything into <layout>), the one which worked for me was doing Build -> Make project. Nor Clean Project or Rebuild Project did. I'm in Android Studio 2.3.1, using 26.0.2 build tools. There's no need for <data> tags.
My solution was to take as a suffix FragmentBinding in the class name.
A binding class is generated for each layout file. By default, the name of the class is based on the name of the layout file, converting it to Pascal case and adding the Binding suffix to it. The above layout filename is activity_main.xml so the corresponding generated class is ActivityMainBinding. This class holds all the bindings from the layout properties (for example, the user variable) to the layout's views and knows how to assign values for the binding expressions.
The nomenclature of the name of the activity or fragment class may vary in terms of prefixes. Because the suffix is always Binding.
After following the response of Khemraj and Invalidate Caches / Restart, you should rewrite ActivityBinding or FragmentBinding to get the IDE suggestions of the classes that were already generated and DO NOT hardcode the import.
In my case I was trying to import the name of the class backwards be FragmentCompetitionsBinding instead of CompetitionsFragmentBinding.
GL
Source
I had the same problem. I made a mistake while I refactored.
The autogen binding class has its name from the xml layout file.
fragment_name.xml -> FragmentNameBinding
Most of time it just need to rebuild. not build not make project . and it will be better if you first of all do invalid Caches and restart Android studio then clean and rebuild it .
Data binding classes are generated during the build so after you enable data binding in the Gradle build of the app and surround your xml with the layout tag you should rebuild your app. If that doesn't help, delete your build folder and do it again.
I do not know it will work for you or not. Just rename the layout XML file name. Like suppose your layout name is activity_main.xml just change rename it to anything like main.xml and again rename it to activity_main.xml. Then you can able to see the import option on ActivityMainBinding.
Hope it works for you.
Thanks to this answer here - it looks like the "layout namespace" needs to either be cleared out, or you need a new unique name.
Here are the options that worked for me:
Create a fresh name for the layout to make sure it can be generated. This solved my issue, where I had a layout that was first created, without data binding - let's call it fragment_abc.xml. When I tried to add data binding to it, it was not recognized - even after multiple clear cache & restart calls. However, soon as I made a copy of the layout fragment_abc2.xml, immediately I got the generated data-binding .java/.class object.
After seeing the above work, I tried to just remove the /build folder from the module, and rebuilt the project - this worked to get data binding for the original layout.
When you work with a multimodule Android application check your binding class path. Maybe you should use:
import com.yourcompany.app.android.modulename.databinding.FragmentABCtBinding
insted of:
import com.yourcompany.app.android.databinding.FragmentABCtBinding
In my case, I thought that generated class had to appear with my usual classes in src folder. In addition, I thought that the name of the generated class should be slightly different. It all was my mistake. The generated class can be found in build folder, build -> generated -> ... path. If there is no import of the generated class in your activity, add the import
import com.yourcompany.app.databinding.ActivityMainBinding;"
Delete layouts and undo, and make sure the generated binding classes are imported correctly after that.
Make sure data binding enabled
android {
...
dataBinding {
enabled = true
}
...
}
dan click the button (Sync project with Gradle)
If answer did not work for you, then my recommendation is simple but effective.
The idea is to determine which is the component that is generating the problem. To do this, comment on all the lines of your custom_fragment.xml and its uses in the CustomFragment.kt and leave something minimalist like the following.
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/test"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</layout>
Then run the app and add component to component while you Apply Code Changes (Ctrl+Alt+F10) to the execution of the app until the app crashes, that is when you found the fault.
Data binding logs are sometimes not so descriptive and this is a generic strategy to find the faulty component.
GL
The only thing I can imagine if possible is if you don't have
dataBinding {
enabled true
}
in your gradle file. If not just add it to the gradle file.
i.e
android {
......
dataBinding {
enabled true
}
}
then sync your project. If it still fail, you may need to do Invalidate/Restart of your android studio
I had same problem. Everything you done correct. Thing is you need add variable inside data tag in xml. For that you should create a sample model class and add it as variable in data tag.
Until that you won't get to see generated ActivityMainBinding.
1.Add Below in app gradle
dataBinding {
enabled = true
}
2.In xml layout write below code
<layout
xmlns:android="http://schemas.android.com/apk/res/android">
<data></data>
</layout>if you don't get data binding class just rename the layout file name and you will get data binding class.
I had a similar issue where I had the layout wrapped and my data binding enabled in the gradle file. Main activity still couldn't intellisense or see my classes. What fixed it for me was adding the binding variable and importing the binding anyway. From there I just built the solution and then it seemed to know what the class was. From there I was able to import my camel case classes that were generated.
I got the issue and the problem was in the layout the field used was not a String, it was a Date.
Looks that all field got to be text to work, at least with the TexView component.
If you build with the command
./gradlew build --stacktrace
This show better the errors.
In case you get the following error in DataBindingUtil.setContentView
Unresolved reference: activity_main
all you need to do is remove the following import statement
import android.R
I found the solution on another forum. Source
If Recently any one migrated existing project into androidx then you need to replace your import from
import com.yourpackagename.BR;
to
import androidx.databinding.library.baseAdapters.BR;
After Google 2 days finally got solution, which one work for me.
There are cases when you won't see a file under generated directory, you might be binding a property that is not declared in viewmodel. It doesn't essentially give you a lint error if you do so in xml.
If you are implement the Serializable -> you must implement the Serializable
else you will get this error. Hope it will help someone in future
In my case I use the Parcel library. I missed to annotate #Parcel in my sub class
In addition to the above steps, you can also check the variable type. Make sure it's String for TextView or the same as defined in the BindingAdapter.
For example:
data class MyDataObject(val name: String, val age: Int)
and in XML:
android:text="#{dataobject.age}"
This will cause the above error. To fix you can either make the age variable of type String or you can import String in your XML and use String.valueOf(age) as following:
<data>
<import type="String" />
...
</data>
And in your TextView:
android:text="#{String.valueOf(dataobject.age)}"
In my case, data binding classes were not generated because I had deleted the mipmap Android Resource Directory. I recreated the res/mipmap/ directory and the data binding classes were reinstated.
I encountered a similar issue where DataBinding failed to generate the BindingImpl class.
In my case was an issue from a method in the data class where the name was used wrong:
The model contained a method onSignInCliked() and in the layout I used onSigninCliked(). Notice the SignIn vs Signin.
The error message wasn't enough and I discovered the issue only when I used the build script with the stack-trace option.

Change activity's layout by an XML string contained in main memory in runtime

I have an activity that is displaying to user. On the activity I have a button. Every time when user pushes the button, the app will load an xml file from a remote server. The xml file is actually a layout designed for the application. Right after the new xml file is loaded and stored in the newLayout variable, I would like to set the xml file to replace the current layout that is showing to user.
String newLayoutStr = "";
onClickButton() {
newLayoutStr = loadNewLayoutFromRemoteServer();
}
// set the layout contained in newLayoutStr as new layout of the current activity
Any comments?
This will not be possible with what your asking. Android relies on Resource identifiers using a class call R which is automatically generated. The file contains public static final int references for various class values in your application. The classes referenced here can be found at http://developer.android.com/reference/android/R.html
This class is than used to reference the various resources in your application, one of which is layout. So the system expects all layouts defined in xml to be included in this generated R class.
So in one sentence: you will not be able to accomplish this the way you want.
What i would do is have a json response and convert it to dynamically generated layout.
for XML you download test.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:layout_width="match_parent">
<TextView android:id="#+id/textViewTest"
android:layout_centerInParent="true"
android:gravity="center"
android:layout_height="wrap_content"
android:layout_width="match_parent"/>
</RelativeLayout>
If you want to have this layout created in your app create a json response:
{
"layout_parent":"RelativeLayout",
"layout_height": "match_parent",
"layout_width": "match_parent",
"layout_children": [
{
"layout_child":"TextView",
"layout_child_id":"textViewTest",
"layout_height":"wrap_content",
"layout_width":"match_parent",
"layout_gravity":"center",
"layout_centerInParent":"true"
}
]
}
i would then parse this to a model object and use that model object to build your layouts dynamically. In order to add the fields though you will need to have some layout you defined in xml to be able to add more fields to in your app.
As far as I know its currently not possible to load Layout dynamically at runtime that were not available at compile time. This is because the LayoutInflater needs a resource ID(from the R class) and this is determined at compile time. An alternative will be to implement a custom LayoutInflater(by borrowing some ideas from the LayoutInflater class) that can do this though this will be very slow as a lot of optimization is done at compile time
I'm not sure this can be done at runtime from memory. You may be able to marshall the XML and save it to the SD card, then load it as a resource using the AssetManager
From there you can inflate the XML using getLayoutInflater().inflate(YourResourceID, TheRootView)

No resource identifier found for

When I try to refactor an app, I get hundreds of "No resource identifier found for (...)" Errors "in package com.app"
How can I solve this Problem?
I already tried to replace the values to the new package Name but the error remains the same.
The Errors happen at such code parts:
<com.example.app
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:latin="http://schemas.android.com/apk/res/com.fa.ime"
android:id="#+id/LatinkeyboardBaseView"
android:layout_alignParentBottom="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="#dimen/keyboard_bottom_padding"
android:background="#drawable/keyboard_dark_background"
android:textStyle="bold"
latin:keyBackground="#drawable/btn_keyboard_key_gingerbread"
latin:keyTextStyle="bold"
/>
R class, used to access resources in android, linked to use package name from Android.manifest. Replace in all imports of R class old package name for new package name. Unfortunately you only can use standard text search in this case.
As far as i know, only this class uses package name from manifest, so other imports should be fine.
I don't use Android support package, but if you using it, in every layout associated with activity, there can be parameter named tools:context which include reference to activity. If you changed package name of app, this also could be a source of your problems.

How to access Monodroid resources from .java file splash screen

I'm trying to implement a .java splash screen in my Monodroid app in Visual Studio, anyway I want the splash screen to get it's content view from a resouces layout. I'm trying to get it like this:
setContentView(R.layout.AppSplash);
Also tried with:
setContentView(Resource.layout.AppSplash);
And also:
setContentView("#layout/AppSplash");
And I get error messages like this:
package R does not exist
Where R changes for Resources or:
cannot find symbol
symbol : method setContentView(java.lang.String)
location: class SwimmerTimesCalc.SplashActivity
setContentView("#layout/AppSplash");
When I try the #layout/AppSplash option
How can I access the Monodroid resources to set the layout of my Splash Screen?
This should help you get started.
If you were wanting to use a layout specifically for creating your own splash screen and then using that resource to display it in your activity then you can use something like this.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/SplashScreenLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ImageView
android:id="#+id/SplashDefault"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_centerInParent="true"
android:scaleType="centerCrop" />
</RelativeLayout>
Then in your activity you can just set the content view.
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.SplashLayout);
}
I figured out how to access the resources, since the debugger couldnt access the resources I went to the generated resources file that is in the project folder under \obj[This can be debug or release]\android\src and it's called R. While browsing that file I found the layout I was trying to use like this:
public static final int appsplash1=0x7f030002;
I took the resource value from there that is 0x7f030002 and used it like this:
setContentView(0x7f030002);
Anyway as the resources file is autogenerated, adding another layout that goes alphabetically before this may require to do this proccess again.
Having the same problem here. One can find the id of the resource in runtime by it's name and folder like this:
int iconResourceId = context.getResources().getIdentifier("icon", "drawable", context.getPackageName());
So, in the Java files one can use such lookups instead of R.drawable.icon and it will work.
This however is slower (because the lookup is implemented inefficiently on Android) and one would still hard-code the names of resources as strings. If one moves or renames resources in the Mono project, the Java files won't know about this.
Also, one has to type all resource names in lower case, cuz Mono converts the name from .NET-style like "Icon.png" to Android style "icon.png".

Categories

Resources