So, I have the basic structure of creating a custom android view component locked down (i.e. create the view's layout xml, create a class for that view that references the layout xml, and then use the class name in an layout xml that uses the custom view) and that's all fine.
However, if I have a set of custom android UI components, can I combine them to create an even bigger custom android UI component? And if so, how would i reference the "inner" custom android UI components in the class that defines the "outer" android UI component?
The real issue here is that the TypedArray Class used to extract values for a custom UI component has only methods for extracting individual attributes (e.g. there is a "getString()" but no "[] getString()" that would return an array of strings that would then be used to update a set of custom UI components at once).
Is it possible in android to create a composite custom android UI component made up of custom android UI components?
(updated: Here is a link. http://postimg.org/image/nbnfq4nlp/2916ab5b/. Here a set of one QRCode Image, time and location TextViews form one Custom View (QRCodeScanItemView) while a group of QRCodeScanItemViews and the prominent date form another View)
Related
I can create this by using XML. But here my requirement is if I set attribute show_stepCount=3, then 3 views should be drawn on the canvas. I should be able to select one item at a time. I am not able to understand should I inherit my custom class by View or with some other view type to achieve the below UI.
The main purpose of the app is to provide education courses for students.
I have two actors:
Teachers who create the content of the course from inside the android app
where the lesson could be any combination of android views.
Students who view these courses and interact with lessons, may be click button to hear sound (Only view this lessons)
Stage 1 : Implementing drag and drop editor
So far I have been able to create new Views (ImageViews TextViews ... etc) & drop them in new layout.
But once I drop them I have no control on them any longer. Now I am restricted to one style of layout, which I do not want. I want to reach the level of android studio layout editor, where I can add Views, change their position, size, etc.
Stage 2 : Save layout
Would you suggest a way to save layout data to be shown to Students. JSON? XML?
Stage 3: Parsing Layout data
I have implemented XML parser and tested it using a layout that I had created in android studio. However, depending on your suggestion I may change the way I parse the lesson.
Drag & DropLayout Editor - Instructor Layout - Student Layout - Android Studio
I would suggest the following:
Stage 1
Create custom views for all widgets which can be dropped (LinearLayout, ImageView, etc). Let them all implement the following interface:
interface Layout {
Layout getLayout();
LayoutEditor getLayoutEditor();
}
Where Layout is the serializable representation of that view's layout (XML or JSON) and LayoutEditor is another interface which can used to modify the attributes on that View (layout_width, layout_height background, etc)
Stage 2
So after you have dragged and dropped widgets on to say the app canvas you get a view hierarchy of Views which implement Layout interface. Just walk this tree recursively and call getLayout() on each view and stitch together a Layout hierarchy. Which you can then serialize and save.
Stage 3
You deserialize the Layout you saved and walk through the layout tree and recreate the View hierarchy with it.
Check out proteus for some inpiration. This uses JSON layouts to inflate native Android views.
Most popular MVVM-frameworks allow some kind of loops for list type properties. For example Knockout has the foreach-binding. It allows you to loop through the elements of the list property and for each element the markup contained in the foreach-loop is duplicated. Inside the copy, the current element is used as the context for data-binding.
I was looking for something similar in Android, but I only saw the possibility to bind a list to a specific ui-element. But this is bad with respect to declarativeness because I need to create a UI element in code.
Is there a way to simulate something similar using the data binding features from Android? If not, is there a workaround? Or a way to extend the binding syntax?
As #tynn answered, this kind of api is not available.
To achieve the same result, you can setup an adapter for RecyclerView in XML itself. I have implemented this feature in my MVVM library. See Setup RecyclerView from XML itself.
Your XML will look as follows:
<android.support.v7.widget.RecyclerView
bind:items="#{vm.itemVms}"
bind:layout_vertical="#{true}"
bind:view_provider="#{#layout/row_item}" />
<!-- Same arguments for ViewPager-->
<android.support.v4.widget.ViewPager
bind:items="#{vm.itemVms}"
bind:view_provider="#{#layout/row_item}" />
Additionally, there is support for displaying different kinds of child views based on your ViewModel. See Using different types of child views
It's not possible as is. The android databinding library uses static XML layout and binds values to attributes. Creating static layout dynamically is not supported and I assume won't ever be. If you want to create a view hierarchy dynamically you still should use views with adapters. That's something you can do with databindings. Just create your own databinding adapter for binding a list to a RecyclerVier. You could bind to a pair of binding:iterator and binding:layout attributes for example and set the RecyclerVier.Adapter inside the databinding adapter.
I am trying to implement a grouped listview on Android similar to iOS. Therefore, I am trying to write my own custom MvxAdapter that supports grouped section headers. The default MvxListView constructed from axml will create a default MvxAdapter. Since I need to supply my own custom MvxAdapter, I need to create the MvxListview programmatically so I can pass in my own adapter. The problem I am having is at the time of OnCreate of my android view where I try to construct my custom MvxAdapter, the Android binding context is null as retrieved from
MvxAndroidBindingContextHelpers.Current()
Is there an example of constructing an MvxListView programmatically with a custom MvxAdapter with v3 API?
There's no examples of creating an MvxListView programatically - almost all Android UI controls are created in axml in the current samples.
For creating custom adapters, there are a few examples around, inclduing:
an example in the polymorphic list in the collection at: https://github.com/slodge/MvvmCross-Tutorials/tree/master/Working%20With%20Collections
an advanced example in the https://github.com/slodge/MvvmCross-Tutorials/blob/master/Sample%20-%20CirriousConference/Cirrious.Conference.UI.Droid/Views/SessionsLists/BaseSessionListView.cs
Alternatively, you can, of course, inherit a CustomListView from MvxListView and can then pass in your custom adapter as part of the constructor.
For more on creating and using custom views, see http://slodge.blogspot.co.uk/2013/05/n18-android-custom-controls-n1-days-of.html
In the event that you ever do want to push a context onto the stack you can do this using:
using (new MvxBindingContextStackRegistration<IMvxAndroidBindingContext>(**TheContext**))
{
// create your controls here
}
This is exactly what happens during xaml inflation - see: https://github.com/slodge/MvvmCross/blob/v3/Cirrious/Cirrious.MvvmCross.Binding.Droid/BindingContext/MvxAndroidBindingContext.cs#L47
I have created a compound control that I am reusing in multiple activities. This control contains a bunch of TextViews and Buttons, and most importantly a ListView. I define the XML in a layout file and in the constructor to this compound control, I inflate the XML as such:
String service = Context.LAYOUT_INFLATER_SERVICE;
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(service);
inflater.inflate(R.layout.map_menu, this, true);
The layout XML contains a ListView, and also in the constructor this compound control will handle setting up the adapter (my adapter extends ArrayAdapter) and array for it, like so:
ListView tableOfContentsList = (ListView) findViewById(R.id.tocListView);
_layerAdapter = new LayerAdapter(context, R.layout.toc_layer_item, _layers);
tableOfContentsList.setAdapter(_layerAdapter);
This compound control is used in two activites - one of these activities calls another. No relation between the two activities is intended.
Here is my problem. When the compound control is created in the initial activity, the above code is called to set the adapter of this control. Then, when the second activity is created and navigated to, the constructor is called again on this second instance of the control. This seems to have a side effect on the first control located in the initial activity. The second control seems to overwrite parts of the adapter from the first control - because basically the first adapter will not be functional once the constructor to the second control is called.
It is my guess that since I am referencing the resource ID of the ListView in both controls, Android is removing the adapter from the first ListView when the second ListView is created - because it sees both ListViews as having the same resource ID? Is this possible?
I have had trouble before in this exact same case - where multiple compound controls are used in different activities (and multiple times in a single activity) - and the problem was due to inflating from XML layout. My solution to that prior problem was to get rid of the inflating from layout, and instead creating the objects through code. This was acceptable because those compound controls were much simpler and contained only two views - however I feel in the above ListView case, where my compound control has at least ten views in it, it is not an acceptable solution to define each view in code. I need the layout XML.
Has anyone ever experienced this sort of clashing behavior when using custom compound controls that are inflated from XML, and re-used in multiple instances?
From my understanding Android should create a new instance of the widgets each time you inflate the xml. Do you have any static members in you compound widget class?