If you choose template with Settings creating a project in Androdi Studio 3.4, you will see example app with SettingsActivity extending AppCompatPreferenceActivity extending PreferenceActivity extending ListActivity extending android.app.Activity, but not the FragmentActivity which is necessary for creating a ViewModel for SettingsActivityby means of
SettingsViewModel viewModel
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
viewModel = ViewModelProviders.of(this, viewModelFactory).get(SettingsViewModel.class);
}
because of ViewModelProviders.of() may accept only the FragmentActivity as a first argument.
Is it possible to create a ViewModel for AppCompatPreferenceActivity or it is the next reincarnation of hell with preferences from Google?!
This template has been completely redone in Android Studio 3.5 to match the Settings documentation:
The recommended way to integrate user configurable settings into your application is to use the AndroidX Preference Library. This library manages the user interface and interacts with storage so that you define only the individual settings that the user can configure. The library comes with a Material theme that provides a consistent user experience across devices and OS versions.
The AndroidX Preferences Library does not require you to use PreferenceActivity at all - you'll note that it uses AppCompatActivity directly, putting preferences into a PreferenceFragmentCompat. As AppCompatActivity extends FragmentActivity, you will be able to use ViewModel and other AndroidX APIs without issue.
Related
My SettingsActivity currently extends the Android Studio generated class, AppCompatPreferenceActivity which extends PreferenceActivity. Each of the preference screens in the activity are displayed using a PreferenceFragment; which, as of API level 28, is deprecated. The documentation states you should use the PreferenceFragmentCompat class from the support library as an alternative.
The issue is that PreferenceFragmentCompat extends android.support.v4.app.Fragment (instead of android.app.Fragment) which the PreferenceActivity does not support. And there is no PreferenceActivityCompat to fill the role of the of the now inconsequential PreferenceActivity.
Further confusing the issue; the new androidx.preference support library includes its own PreferenceFragment (which extends android.app.Fragment) and PreferenceFragmentCompat (which extends the new androidx.fragment.app.Fragment).
I could always recreate the functionality of the PreferenceActivity with my own classes, but why would the documentation recommend using the PreferenceFragmentCompat without a viable alternative to the PreferenceActivity? Am I missing something, or is the current state of the preference libraries not functional?
The SettingsActivity works as-is for now, but I usually like to try to get ahead of the curve, especially when something becomes deprecated.
Don't use a PreferenceActivity; a regular AppCompatActivity will serve the purpose just fine. If you want, there is a direct method of making a Settings Activity in your app provided by Android Studio:
With the new architecture components of android you can't use the default auto generated class navigation drawer class provided by android... why? because it extends from AppCompatActivity to provide the use of support.v7 lib for widgets like toolbar etc. When using now the new architectures component Lifecycleactivity instead of extending AppCompatActivity you can't implement the default navigation drawer class - can anyone give me a workaround or an example how to do this?
From the Lifecycle documentation:
Note: Since the Architecture Components are in alpha stage, Fragment and AppCompatActivity classes cannot implement it (because we cannot add a dependency from a stable component to an unstable API). Until Lifecycle is stable, LifecycleActivity and LifecycleFragment classes are provided for convenience. After the Lifecycles project is released, support library fragments and activities will implement the LifecycleOwner interface; LifecycleActivity and LifecycleFragment will be deprecated at that time.
They go on to provide instructions for implementing a LifecycleOwner, which allows you avoid using LifecycleActivity:
public class MyActivity extends AppCompatActivity
implements LifecycleRegistryOwner {
LifecycleRegistry lifecycleRegistry = new LifecycleRegistry(this);
#Override
public LifecycleRegistry getLifecycle() {
return lifecycleRegistry;
}
}
I am having an activity that extends appcompatactivity I want to use the methods of activity like getwindow(), setRequestedOrientation() and finish() etc. but not able to do so... It says cannot resolve method. so, is there any way cast AppCompatActivity to Activity.
I am using Android Studio 3.0 Canary 4
For a minimum API level of 15, you'd want to use AppCompatActivity. So for example, your MainActivity would look like this:
public class MainActivity extends AppCompatActivity {
....
....
}
To use the AppCompatActivity, make sure you have the Google Support Library downloaded (you can check this in your Tools -> Android -> SDK manager). Then just include the gradle dependency in your app's gradle.build file:
compile 'com.android.support:appcompat-v7:22:2.0'
You can use this AppCompat as your main Activity, which can then be used to launch Fragments or other Activities (this depends on what kind of app you're building).
The BigNerdRanch book is a good resource, but yeah, it's outdated. Read it for general information on how Android works, but don't expect the specific classes they use to be up to date.
You can cast AppCompatActivity to Activity:
((AppCompatActivity) getActivity()).someAction...
I have an android wear app that contains a FragmentActivity:
public class MyFragmentActivity extends FragmentActivity
With 2 Fragments:
public class MyFirstFragment extends Fragment
and
public class MySecondFragment extends Fragment
I want to enable the ambient mode (always on) in this fragment activity. However, according to the documentation, the ambient mode is only available if i extend WearableActivity.
Is there a way to have both properties of the FragmentActivity & WearableActivity together in one?
or
Is there another way to enable the ambient mode in the FragmentActivity?
You should implement AmbientModeSupport.AmbientCallbackProvider instead of WearableActivity, then you can extend FragmentActivity instead.
It is the new preferred method and it still gives you all the goodies you got with WearableActivity but also lets you use Activity (or any sub classes... FragementActivity, etc.).
Official docs call out the details (and example code).
Update: Use AmbientModeSupport now instead of AmbientMode. Google recently changed the name, so the old version is deprecated.
Answer to both questions is no, sorry.
Ambient mode is enabled by calling WearableActivity.setUseAmbient(), which obviously is not available if you're not extending WearableActivity. And since Java doesn't support multiple inheritance, you can't subclass both WearableActivity and FragmentActivity at the same time - it's one or the other.
Do you really need to be using Fragments on a watch activity? If you really want to support ambient mode, you probably need to look at moving your UI out of fragments.
If you want to use Fragments on Android Wear and support Ambient mode, you need to use the AmbientModeSupport class.
Make your activity extend FragmentActivity and implement AmbientModeSupport.AmbientCallbackProvider and you're all set!
Details and examples are here: https://developer.android.com/training/wearables/apps/always-on#ambient-mode-class
I cannot decide what approach should I use in the next situtation.
One activity from my app need to have different functionality, here is the leak of multiple inheritence comes into play.
What I need to get ?
There are several parts that my activity has to have.
Navigation drawer. I am using MaterialDrawer library. It requires activity to implement on click callbacks (or use composition instead), but also it use activity as constructor argument,so I think it will be better to put this into separate class inherited from Activity or any base class provided by Android Framework . Thanks to library developer it doesn't require any stuff to be done in on create method ( setContentLayout for instance)
My activity(one of several) will have only Toolbar and FrameLayout for holding fragment . Or it is better to separate toolbar and single fragment ?
This in turn requires some stuff to be done in onCreate : setContentLayout with basic layout , add fragment to the container set activity actionbar .....
Maybe in future I will use another libraries that requires to add something in activity lifecycle methods.
All these points in order to follow Single Responsibility principle have to be separate classes inherited from some base Activity.
For example we will have something like this.
public class SingleFragmentActivity<T extends Fragment> extends AppCompatActivity {
}
public class SingleFragmentToolbarActivity<T extends Fragment> extends AppCompatActivity {
}
public class NavigationDrawerActivity extends AppCompatActivity {
}
....
As you can see each functionality is put into the separate class, but what if I need to have SingleFramgentActivity with NavigationDrawer ?
In this case I have to inherit one of these classes from another, for example
public class NavigationDrawer extends SingleFragmentActivity {
}
If to do so, I have no ability to use navigation drawer separately from SingleFragmentActivity.
What is the best practice to follow in this case, how to build class hierarchy to make it flexible and use Open-Close principle, to make changes in application without any pain. (Use strategy, decorator ..... ?)
I would be grateful everyone for help.