I have a layout .xml file and I want to use it frequently (20 times)within another xml file.
of course with different Initializing.i dont want to use include tags for 20 and init 20 times.Is there any way instead of add include tag for 20 times?
Then create custom view
Create custom class extending any ViewGroup like LinearLayout,RelativeLayout etc and handled your code depending on conditions.
public class YourCustomImpl extends LinearLayout {
...
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
inflater.inflate(R.layout.your_common_view, this, true);
...
}
Include your custom implemented view like below
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
...
<your.domain.YourCustomImpl
android:layout_width="match_parent"
android:layout_height="?android:attr/listPreferredItemHeight"/>
</LinearLayout>
For more details there is nice tutorial
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.
Theoretically implementation of multi culture stored in remote DB.
In Android we have the following:
<TextView
android:id="#+id/loginlabel"
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="25sp"
android:textStyle="bold"
android:layout_marginTop="5dp"
android:text="#string/login" />
And the text is using the value of the property login from the file string.xml.
Now my question: in the activity xml in the property android:text is there any way for me to call a function/method (can it even be from a static class) ?
A place that have some business logic and still returns a string.
I know that I can easily use the following type of code in my activity java file:
TextView loginlabel = (TextView) findViewById(R.id.loginlabel);
loginlabel.setText( GetMyText(R.id.loginlabel) );
But I am trying to avoid to write this a "million times" since I have several activities and hundreds of values on my strings.xml.
For adition information, my purpose with this is the following:
On application start I read all the string.xml and connect to my remote server (which has a DB) and verify if all the strings are inserted in that DB.
Insert the ones that are missing, with the default value of that property in string.xml.
Now, in another remote system, the client can dynamically create new cultures and translations of this properties.
back to the android, I load a list of the current cultures that we have available and also load the values (translations) from the DB. The only thing missing it to "inject" them into the place where I am using the "string" value.
This worked for me in the past.
public class MyTextView extends TextView {
public MyTextView(Context context) {
super(context);
}
public MyTextView(Context context, AttributeSet attrs) {
super(context, attrs);
setText(yourMethodWithBusinessLogic());
}
}
Don't forget to replace your normal textviews with this custom one. Press CTRL+SHFT+R for convenience.
Hope this helps.
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);
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
I am building a library project which returns Views based on a user request. However the Views I create in the library project do not use the theme I use in my application.
For example if the library project returns a Fragment which has an EditText in it, then the EditText will not use the AppCompat theme even though the app is using it.
Here is the relevant part of the base class I use to inflate the Views in the library project:
public abstract class AbsInputFieldViewController<T extends AbsInputField> {
protected Context getContext(){
return mFragment.getActivity().getApplicationContext();
}
protected LayoutInflater getInflater(){
return (LayoutInflater)getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public abstract View getView(AbsInputField field, Fragment fragment);
}
getView() is implemented in a few sub classes and it uses the LayoutInflater from getInflater() to inflate a View instance from a layout xml.
The problem is that you are getting the LayoutInflater with getSystemService(). If you want the LayoutInflater to use a specific theme you have to create it from a Context which is using that theme. Usually that would be the Context from an Activity or from your Application. Try this instead:
LayoutInflater inflater = LayoutInflater.from(context);