In official android docs - there is some guidance how to use databinding in fragments and activities. However I have pretty complex picker with high ammount of settings. Something like:
class ComplexCustomPicker extends RelativeLayout{
PickerViewModel model;
}
So my question is what method of the picker I need to override to be able use binding inside it and not seting/checking individual values like textfield, etc?
And second question - how could I pass viewmodel to my picker in xml file, do I need some custom attributes for that?
I think using Custom Setters will solve your problem. Check this section in developers guidelines.
I can give you a brief example for it. Suppose the name of your view is CustomView and of your viewmodel is ViewModel, then in any of your class, create a method like this:
#BindingAdapter({"bind:viewmodel"})
public static void bindCustomView(CustomView view, ViewModel model) {
// Do whatever you want with your view and your model
}
And in your layout, do the following:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/tools">
<data>
<variable
name="viewModel"
type="com.pkgname.ViewModel"/>
</data>
// Your layout
<com.pkgname.CustomView
// Other attributes
app:viewmodel="#{viewModel}"
/>
</layout>
And from your Activity use this to set the ViewModel:
MainActivityBinding binding = DataBindingUtil.setContentView(this, R.layout.main_activity);
ViewModel viewModel = new ViewModel();
binding.setViewModel(viewModel);
Or you can directly inflate from your custom view:
LayoutViewCustomBinding binding = DataBindingUtil.inflate(LayoutInflater.from(getContext()), R.layout.layout_view_custom, this, true);
ViewModel viewModel = new ViewModel();
binding.setViewModel(viewModel);
Related
I'm working on a "home feed"-like feature where there's a main Fragment with several other fragments added to its layout, making up the content page. I'd like the main fragment class to be able to instanstiate all the fragment classes that inherit from a certain parent fragment class. This way the code would be more dynamic instead of adding a bunch of <fragment> tags to my xml files.
I'm kinda stuck on making up a decent architecture. How would you go on about doing this?
UPDATE:
Here's what I'm basically trying to do, but don't know how:
public class FeedFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View parentView = inflater.inflate(R.layout.fragment_home, container, false);
// Get fragments and dynamically add them to
// the FeedFragment's layout
getEntryFragmentsList();
// ...
return parentView;
}
}
public abstract class FeedEntryFragment extends Fragment {
// Somehow add fragment to list of entry fragments
}
public class TestFragment extends FeedEntryFragment {
// Already added to list of entry fragments
}
I don't think that possible to decrease the count of xmls by inheritance. I think you should try to split your xml configurations and use some <merge> or <include> to build the full one from the parts.
May be I can provide more help if you will describe your problem in more details.
You should use FrameLayout to add fragment(s) dynamically by using the FragmentTransaction.
You can also use a ViewPager with tabs or bottom tabs to show multiple fragments. Please check sample from my Dynamic Support library for the complete code.
Abstract fragments
DynamicFragment - Abstract base fragment from the Dynamic support library.
DynamicViewPagerFragment - Abstract fragment which extends the DynamicFragment to implement the ViewPager functionality.
Implementation
HomeFragment - Sample fragment extends the DynamicFragment to implement the home screen.
SettingsFragment - Sample fragment extends the DynamicViewPagerFragment to implement the settings functionality using multiple fragments inside a view pager.
Tutorial Implementation
This better suits your need. TutorialActivity returns a list of fragments to be displayed inside a ViewPager.
DynamicSimpleTutorial generates a DynamicTutorialFragment according to the supplied parameters.
I want to hide and show my views from code. One option is to use View.VISIBLE from my ViewModel but that will impact the testing of the code in ViewModel.
I have read that it's not good practice to use Android specific things from ViewModel.
Either I can make an interface and interact with the view, but that will have a reference to the view. Will that be a good approach? I am currently not using ViewModel Lifecycle Component and extending my class with BaseObservable.
Eg.
I have
#Bindable
public int getButtonsVisibility() {
//return visibility
}
and
public void setButtonsVisibility(int buttonsVisibility) {
this.buttonsVisibility = buttonsVisibility;
notifyPropertyChanged(BR.buttonsVisibility);
}
Now If I want to call setButtonsVisibility(View.VISIBLE) from my viewModel, what will be a good approach?
I follow this approach to manage visibility ..
<data>
<import type="android.view.View"/>
<variable
name="visible"
type="java.lang.Boolean"/>
</data>
<View android:visibility="#{visible ? View.GONE : View.VISIBLE}"/>
I am writing a react native application and I want to use some of the static layouts (for Android) I have from my old application.
I looked at https://facebook.github.io/react-native/docs/native-components-ios.html and wrote a few classes (MyViewManager.java and MyView.java).
I want to be able to use the static layouts I have for MyView.java.
I went through the facebook's react native code on github.
I could not find an appropriate method like setContentView(R.layout.myview). I was wondering if anybody tried this and this will work.
Can someone please help me with this problem?
You can try out something like
The layout inflater will inflate given xml file and put it as a child of this(second argument in inflate), which is MyLayoutView.
See the definition of inflate and change arguments as per customization required.
public class MyManyViewsManager extends ViewGroupManager<MyLayoutView> {
}
class MyLayoutView extends FrameLayout {
init() {
rootItem = (ViewGroup) LayoutInflater.from(getContext()).inflate(R.layout.xmlfilename, this, true);
}
}
I'm new in android studio and I'm having problem with drawing. I understood that "onDraw()" function can only be implemented in class that extendes "View". But I don't under how do I connect my activity to the view class, so we will see on the screen the view class, not the activity one.
Any help? Thanks in advance!
Its a pretty much basic thing android. You can find more info here.
I'll just show you an example.
First the View class,
public MyView extends View{
public MyView(Context context,AttributeSet set){
super(context,set);
}
public void onDraw(Canvas canvas){
//draw the item
}
}
In XML
<LinearLayout xmlns:android="http://www....."
android:orientation="veretical"
android:width="match_parent"
android:height="match_parent">
<!--you custom view here-->
<com.your.package.name.MyView
android:width="match_parent"
android:height="match_parent"/>
</LinearLayout>
Use this XML as the content view of your activity.
Just add your's custom view object to realtive layout.Hear Relative is where you want to see canvas it may complete layout or portion of the layout
RelativeLayout viewlayout=(RelativeLayout)findViewById(R.id.viewlayoutid);
viewlayout.addView(new yours_customviewclass(this,null));//yours_customviewclass is your custom view means which extends view class,overide ondraw methods in this class
We have in our project a keyboard with "Key" elements, this Key elements have attributes such as android:codes="119", android:keyLabel="w" and so on.
My question is how can I include an custom attribute like a "android:alternativeKeyLabel" to do something else.
This link gives a superficial explanation:
http://developer.android.com/guide/topics/ui/custom-components.html
Considering you have a CustomKeyboard that inherits from KeyboardView/View:
Create your custom properties in res/values/attrs.xml file (create the file if it does not exist):
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="custom_keyboard">
<attr name="alternative_key_label" format="string" />
</declare-styleable>
</resources>
Create a constructor in your custom component overriding default constructor that receives the attribute set because this one will be called when the layout is loaded.
public CustomKeyboard(Context context, AttributeSet set) {
super(context, set);
TypedArray a = context.obtainStyledAttributes(set,R.styleable.custom_keyboard);
CharSequence s = a.getString(R.styleable.custom_keyboard_alternative_key_label);
if (s != null) {
this.setAlternativeKeyLabel(s.toString());
}
a.recycle();
}
In your layout file, add your custom component and the link to your resources.
<Layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res/your.package.ProjectName"
.../>
...
<your.package.projectname.CustomKeyboard
android:id="#+id/my_keyboard"
...
app:alternative_key_label="F">
</your.package.projectname.CustomKeyboard>
</Layout>
For any other purpose, declaring a custom property in the XML file can be retrieve with attrs constructor parameter.
In my case I reuse a preference custom dialog, and set things like that:
<?xml version="1.0" encoding="utf-8"?>
<!-- something here -->
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<your.package.projectname.CustomView
foo="bar"
/>
</PreferenceScreen>
Then in my class contructor:
public CustomView(Context context, AttributeSet attrs) {
String bar = attrs.getAttributeValue(null, "foo");
Log.d("CustomView", "foo=" + bar);
}
You can create custom attributes for your own classes that extend View or a subclass. The process is documented in the "Creating a View Class" section of the Android Dev Guide under the heading "Define Custom Attributes":
https://developer.android.com/training/custom-views/create-view#customattr
android:keyLabel is one of many XML attribute used by the Keyboard.Key class for each key on your keyboard. android:keyLabel is what you want to label the key with (like a "w" as in above). The attributes are pre-defined for the class. The "w" isn't but android:keyLabel is. If you could create android:alternativeKeyLabel what would you expect the class to do with it? I think maybe you should try to explain further what you are trying to accomplish.