.setCustomAnimations(R.animator.in_animation, R.animator.out_animation)
the following throws "Expected respource type of anim"
getSupportFragmentManager()
.beginTransaction()
.setCustomAnimations(R.animator.in_animation, R.animator.out_animation)
.replace(R.id.a_fragment, SingleAnswerFragment.newInstance())
.addToBackStack(null)
.commit();
I did check this stack over flow thread Android Studio's "expected resource of type" checks? and I did see where in this case I might use #Animator Res annotation, but i'm not sure how I would use that in the middle of my method chaining as shown above
https://stackoverflow.com/a/18511350/5596604 Here I see a possible solution but have no idea what he means in his steps where he, (Imported the NineOldAndroids library into the support-v4 Library
Imported the support-v4-nineoldandroids library into my project.) The github link for that support library for NineOldAndroids, states in the configuration part " remove Google's support v4 library from your classpath."
You are providing R.animator resources (#AnimatorRes) to the setCustomAnimations() method but it expects R.anim resource type (#AnimRes). If you switch to some animations which are referenced by R.anim it should compile and work.
but i'm not sure how I would use that in the middle of my method chaining as shown above
I'm not sure what you mean by this. Maybe this could shed some light on the matter. Also here you can find a list of all the Android annotations with short descriptions.
You can use setCustomAnimations with Property Animation only with android.app.Fragment. And with android.support.v4.app.Fragment you should use TweenAnimation.
I'm pretty sure that you are using fragment of class android.support.v4.app.Fragment, but not android.app.Fragment. This class is not allowing property animation that you try to use.
If so, change your fragment to android.app.Fragment (change all other accordingly, for example getSupportFragmentManager() to getFragmentManager()), this should help.
Related
#anim/fragment_fade_enter was included in androidx.fragment:fragment-ktx:1.2.4 but after I updated it to version 1.3.3 I can't seem to be able to resolve it anymore, all I can find online that it's supposed to be included in Androidx Core https://android.googlesource.com/platform/frameworks/base/+/master/core/res/res/animator/fragment_fade_enter.xml
but using androidx.core:core-ktx:1.3.2 doesn't help either.
Did it get refactored into another dependency?
The #anim/fragment_ resources were always a private implementation detail of the various FragmentTransaction.TRANSIT_ fields (i.e., TRANSIT_FRAGMENT_FADE) used in the FragmentTransaction.setTransition() API.
As per the Fragment 1.3.0 release notes:
TRANSIT_ animation changes: The fragment default effects, TRANSIT_FRAGMENT_OPEN, TRANSIT_FRAGMENT_CLOSE, and TRANSIT_FRAGMENT_FADE, now use Animator instead of Animation. The resources used to build these animators are now private.
So if you are using Fragments by themselves, you should use the setTransition() API, rather than manually using any of those private animators.
If you are using the Navigation Component, the navigation-ui dependency does offer public animators as of the Navigation 2.3.1 release. You'd use those with:
#animator/nav_default_enter_anim
#animator/nav_default_exit_anim
#animator/nav_default_pop_enter_anim
#animator/nav_default_pop_exit_anim
As of this time, those are also fade animations.
I'm currently trying to share data between my two fragments with the help of a view model Android ViewModels.
In the this article they use "ViewModelProviders.of(getActivity()).get(SharedViewModel.class);" in the Fragment to get the model.
My Problem is, that when I write the exact same line into my fragment, I get a "Cannot resolve method of(android.app.Activity)" error
model = ViewModelProviders.of(getActivity()).get(UserAccountViewModel.class);
Can some one help me with this ?
ViewModelProviders requires that you use FragmentActivity (or something derived from it), not Activity, as the base class of your activities.
You might also get a similiar error like Cannot resolve method 'of(android.support.v4.app.FragmentActivity)' from ViewModelProviders.of(getActivity()) if you were trying to import androidx in your gradle file when your app is still using android.support.v4
This is different to the question being asked but is in the same ballpark and ranks first in Google when I had the problem, so I'm posting it!
Just cast getActivity() to specific activity. It works for me. For example:
model = ViewModelProviders.of((MainActivity)getActivity()).get(UserAccountViewModel.class);
I'm with a cross-API problem. My scenario is as follow:
I'm developing an application that uses support-v4-AppCompat, using android.support.v4.app.Fragment;
I'm using getChildFragmentManager to retrieve nested Fragments. This is a need because I have a PageView to scroll along several Fragments, one of them using com.google.android.gms.maps.SupportMapFragment as nested Fragment;
I also have a need to use ShinobiCharts as our solution is being developed with it. ChartFragment is a subclass of android.app.Fragment.
Problem comes when I try to use a nested fragment like this:
<fragment
class="com.shinobicontrols.charts.ChartFragment"
android:id="#+id/chart"
android:layout_width="match_parent"
android:layout_height="match_parent" />
And retrieve reference to it from another Fragment like this:
public class TCPSpeedFragment extends android.support.v4.app.Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FragmentManager fragMan = getChildFragmentManager();
// BELLOW LINE GIVES ERROR OF TYPE CONVERSION
android.app.Fragment frag = fragMan.findFragmentById(R.id.chart);
}
As we can see, the given error is a Type mismatch: cannot convert from android.support.v4.app.Fragment to android.app.Fragment. But when trying to convert them it becomes a really pain, that I haven't found solution yet.
Does anyone have an idea to solve this compatibility/conversion issue?
Firstly, I don't believe that you can get a reference to a nested Fragment that is defined in XML. That in itself is wrong: nested Fragments can only be added & removed programmatically, and I'm surprised that you have not thought of this as a potential issue. The way you have defined that Fragment in XML and then tried to get a reference to it by calling findViewById() is incorrect.
Now coming to your main question, there is, unfortunately, NO way to cast android.support.v4.app.Fragment to android.app.Fragment. You have the following options:
see if the library has a Fragment that can be used with the v4 support library
if the library is open-source, try to modify it so that it uses android.support.v4.app.Fragment instead of android.app.Fragment
if it is not open source, you can either stop using the library and try to find another that does, or you can drop support for android.support.v4.app.Fragment in your project and instead make use of android.app.Fragment everywhere in your app.
Hope this is useful.
Well.. I think that I have found a solution for me, in the way that I was looking for. I'm using the following lines:
Fragment frag = getChildFragmentManager().findFragmentById(R.id.chart);
SupportChartFragment supportFrag = (SupportChartFragment)frag;
ShinobiChart shinobiChart = supportFrag.getShinobiChart();
With this, I can now compile my project with no errors.
My Current Situation
I am working on an existing app that is using CustomFragment derived from android.app.Fragment. I want to add a new functionnality with a ViewPager which will show my CustomFragments. For that I need to use a FragmentPagerAdapter.
Oooh snap !
Here I am, importing android.support.v4.view.ViewPager and android.support.v4.app.FragmentPagerAdapter to achieve my goal. And now the funny part begins :
When I try to use my FragmentPagerAdapter with my CustomFragment, I get the classic error Type mismatch: cannot convert from android.app.Fragment to android.support.v4.app.Fragment
Knowing that I can't change the whole app fragments to android.support.v4.app.Fragment, I searched and found that the android.support.v13.app.FragmentPagerAdapter was made to use native fragments. Great !
Not great. When I try to import the v13 FragmentPagerAdapter, I get the error The import android.support.v13 cannot be resolved. For the record, I checked in SDKManager what support version is installed : v19.0.1
I searched again, because of course I can't be the first one with that problem. I found that you can't use support.v4 and support.v13 in the same app because v4 is included in v13. And for everyone that encoutered my problem, the solution was to use only android.support.v4.app.FragmentPagerAdapter and android.support.v4.app.Fragment
What to do now ?
Since I have to use android.app.Fragment and I can't use only support.v4, I don't know where to go search next. Any help would be highly appreciated !
Well that is simply not possible. I went to use support.v4.app.Fragment.
I'm looking to write preferences that can be applied to both 3.0 and pre-3.0 devices. Discovering that PreferenceActivity contains deprecated methods (although these are used in the accompanying sample code), I looked at PreferenceFragement and the compatibility package to solve my woes.
It appears, though, that PreferenceFragment isn't in the compatibility package. Can anyone tell me whether this was intentional? If so, can I easily target a range of devices (i.e. < 3.0 and >=3.0) or will I have to jump through hoops? If it wasn't intentionally excluded, can we expect a new release of the compatibility package? Or is there another workaround that is safe to use?
Discovering that PreferenceActivity contains deprecated methods (although these are used in the accompanying sample code)
The deprecated methods are deprecated as of Android 3.0. They are perfectly fine on all versions of Android, but the direction is to use PreferenceFragment on Android 3.0 and higher.
Can anyone tell me whether this was intentional?
My guess is it's a question of engineering time, but that's just a guess.
If so, can I easily target a range of devices (i.e. < 3.0 and >=3.0) or will I have to jump through hoops?
I consider it to be done "easily". Have two separate PreferenceActivity implementations, one using preference headers and PreferenceFragments, the other using the original approach. Choose the right one at the point you need to (e.g., when the user clicks on the options menu item). Here is a sample project demonstrating this. Or, have a single PreferenceActivity that handles both cases, as in this sample project.
If it wasn't intentionally excluded, can we expect a new release of the compatibility package?
You will find out when the rest of us find out, which is to say, if and when it ships.
Or is there another workaround that is safe to use?
See above.
The subtle implication of the answer from #CommonsWare is that - your app must choose between the compatibility API or the built-in fragment API (since SDK 11 or so). In fact that's what the "easily" recommendation has done. In other words, if you want to use PreferenceFragment your app needs to use the built-in fragment API and deal with the deprecated methods on PreferenceActivity. Conversely, if it's important that your app use the compat. API you will be faced with not having a PreferenceFragment class at all. Thus, targeting devices is not a problem, but the hoop-jumping happens when you have to choose one or the other API and thus submit your design to unforeseen workarounds. I need the compat. API so I'm going to create my own PreferenceFragment class and see how that works. In the worst case scenario I'll just create a normal (fragment) layout and bind the view components to the sharedprefs manually...ugh.
EDIT:
After trying and looking at the code at http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.0.1_r1/android/preference/PreferenceFragment.java?av=h -- creating my own PreferenceFragment isn't going to happen. It appears the liberal use of package-private in PreferenceManager instead of 'protected' is the main blocker. It really doesn't look like there's any security or really good motivation to have done that and it isn't great for unit-testing but oh well...less typing I guess...
EDIT v2:
Actually it did happen and it worked. It was definitely a headache to make the code work with the Compatibility API JAR. I had to copy about 70% the com.android.preference package from the SDK to my app and then wrestle with typically mediocre-quality Java code in Android. I used v14 of the SDK. It would have been much easier for a Goog engineer to do what I did, contrary to what I've heard some lead Android engineers say about this topic.
BTW - did I say "targeting devices is not a problem"? It totally is...if you use com.android.preference you are not going to be able to swap out with the Compatibility API without major refactoring. Fun log!
Building upon CommonsWare's answer as well as Tenacious' observations, I have come up with a single descendant class solution capable of targeting all current Android API versions with minimal fuss and no code or resource duplication. Please see my answer to the related question over here:
PreferenceActivity Android 4.0 and earlier
or on my blog:
http://www.blackmoonit.com/2012/07/all_api_prefsactivity/
Tested on two tablets running 4.0.3 and 4.0.4 as well as a phone running 4.0.4 and 2.3.3 and also an emulator running 1.6.
See PreferenceFragment-Compat from Machinarius. It was easy to drop in with gradle and I forget that it's even there.
compile 'com.github.machinarius:preferencefragment:0.1.1'
Important Update: The latest revision of the v7 support library now has a native PreferenceFragmentCompat.
On August 2015 Google released the new Preference Support Library v7.
Now you can use the PreferenceFragmentCompat with any Activity or AppCompatActivity
public static class PrefsFragment extends PreferenceFragmentCompat {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Load the preferences from an XML resource
addPreferencesFromResource(R.xml.preferences);
}
}
You have to set preferenceTheme in your theme:
<style name="AppTheme" parent="#style/Theme.AppCompat.Light">
...
<item name="preferenceTheme">#style/PreferenceThemeOverlay</item>
</style>
In this way you can customize the preferenceTheme to style the layouts used for each preference type without affecting other parts of your Activity.
Tenacious's answer is correct, but here are some more details.
The reason you can't "create a normal layout and bind the view components to the sharedprefs manually" is that there are some surprising omissions in the android.preferences API. PreferenceActivity and PreferenceFragment both have access to critical non-public PreferenceManager methods, without which you can't implement a preference UI of your own.
In particular, to construct a Preference hierarchy from an XML file you need to use a PreferenceManager, but all of PreferenceManager's constructors are either package-private or hidden. The method of attaching the Preference onClick listeners to your activity is also package-private.
And you can't work around this by sneakily putting your implementation in the android.preferences package, because non-public methods in Android APIs are actually omitted from the SDK. With a bit of creativity involving reflection and dynamic proxies, you can still get at them. The only alternative, as Tenacious says, is to fork the entire android.preference package, including at least 15 classes, 5 layouts, and a similar number of style.xml and attrs.xml elements.
So to answer the original question, the reason Google didn't include PreferenceFragment in the compatibility package is that they would have had exactly the same difficulty as Tenacious and myself. Even Google can't go back in time and make those methods public in the old platforms (though I hope they do that in future releases).
My app target is API +14 but due to using support library for some fancy navigation, I couldn't use the android.app.Fragment and had to use android.support.v4.app.Fragment, but I also needed to have PreferenceFragment in place without large changes to code behind.
So my easy fix for having both worlds of support library and PreferenceFragment:
private android.support.v4.app.Fragment fragment;
private android.app.Fragment nativeFragment = null;
private void selectItem(int position) {
fragment = null;
boolean useNativeFragment = false;
switch (position) {
case 0:
fragment = new SampleSupprtFragment1();
break;
case 1:
fragment = new SampleSupprtFragment2();
break;
case 2:
nativeFragment = new SettingsFragment();
useNativeFragment = true;
break;
}
if (useNativeFragment) {
android.app.FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.content_frame, nativeFragment).commit();
} else {
if (nativeFragment != null) {
getFragmentManager().beginTransaction().remove(nativeFragment)
.commit();
nativeFragment = null;
}
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.content_frame, fragment).commit();
}
}
I needed integrate Preferences into application's design and keep support for 2.3 android. So I still needed PreferencesFragment.
After some search I found android-support-v4-preferencefragment lib. This lib save a lot of time for copying and refactoring original PreferencesFragment as Tenacious said. Works fine and users enjoy preferences.