Create a composite view in Android - java

I'd like to create a custom view (I'll call it MyComplexView), for example a RelativeLayout with an Imageview, a TextView, and a Button.
I'd like to declare an xml with the layout and then create the class:
MyComplexView extends RelativeLayout{...}
But I don't know what I should override to indicate which layout should be inflated.
How can I do this? Thanks

Something like this:
add the constructors from the super class. (the one with just context is for creating the views programaticaly, the others are for when you add the view in XML.
create a method called init() for example and call it from each constructor.
inside the init method do:
LayoutInflater.from(context).inflate(R.layout.my_view_layout, this, true);
now in inflate the additional params actually mean:
true -> attach the layout to the root in your case relative layout (pro-tip: so inside the xml you can have just merge tags if your layout root is also relative layout and align them in code so the hierarchy is simpler) or any layout you like.
this -> the layout to attach the inflated view to in your case the relative layout you are extending.
it will automatically be attached to the root -> extends RelativeLayout.
then you can use findViewById like:
this.findViewById(R.id.myView);

I'm not 100% sure what your main goal is, so I try to be thorough:
If you want to include a complex layout in other layouts, then you can simply define my_complext_layout.xml, and in your other layouts put:
<include layout="#layout/my_complext_layout" />
If you need to run your own code, then you could simply make the root of this layout to be MyComplexView, and you can run code when the view is created.
If you have intended to let your code operate on the layout, then simply implement an OnGlobalLayoutListener and add it to your layout in your views constructor.

Implement a Constructor for the MyComplexView:
public MyComplexView(Context context, AttributeSet attrs){
LayoutInflater inflater = LayoutInflater.from(context);
inflater.inflate(R.layout.header_view, this, true);
mHeaderView = (TextView)findViewById(R.id.header);
if(mHeaderView != null)
mHeaderView.setText("Test");
}

See Custom Components in the developer docs. In particular the Compound Controls section.
Once you've made your java file, in order to refer to it in xml you'll have to use a fully qualified packagename i.e:
<com.yourpackage.YourCustomView
android:layout_height="wrap_content"
android:layout_width="wrap_content" />

Creating a custom view usually is aimed to create a widget which doesn't exist yet. What you're trying to do is to have the same layout repeated at multiple places.
You have severall options to do that according to your context.
If the layout is to be placed in a lest, just create your layout in a separate file, and use it in a ListAdapter. Take a look at the ListView Tutorial for this.
If this layout is a generic layout to be embedded in multiple activities, try using a Fragment instead. Fragments are subparts of an activity, with their own views. Alternatively, you can just embed the layout in severall xml using the tag.
If really you want a custom class and single widget, then you need to extend the View class. Extending a layout means you wan't to organize child widgets differently (for example, organize them in circle). Extending a View, you can have exactly what you want (button, image, text) organized always in the same way. But I won't lie to you, this will mean lot of work.

Related

Accessing layout from inside Vaadin 23 view

I'm using Vaadin 23.
I defined a "MainLayout" class to carry the drawer among other things.
In my view declaration, i have the annotation :
#Route(value = "", layout = MainLayout.class)
In the view, if I try
this.getParent();
the returned optional is empty.
So, how can I call a method in my MainLayout class from my view instance ?
UI event bus
Instead of creating strong coupling between your views and main layout, you can use the Eventbus with custom events thrown by your view and your layout listening on them.
You can find a official example in the cookbook of Vaadin, Communicate between components attached to one UI.
I'd try with:
UI.getCurrent().getChildren()

Editing layout xml attributes not displaying changes, but able to by getting reference to the view objects and calling its layout changing methods

Essentially I can't get the View's layout attributes to register on the UI unless I programmatically call, for instance, textViewInstance.setTextColor(rainbow). Any ideas as to why?
Edit: I meant that the following code works:
messageTextView.setTextColor(getResources().getColor(R.color.headline));
BUT doing the following in the view's layout xml does NOT:
#+id/messageTextView
...
textColor="#color/headline"
Try This method...
tv.setTextColor(Color.parseColor("#C10000"));
OR
String rainbow = "#C10000";
tv.setTextColor(Color.parseColor(rainbow));

ViewStub - Show view with dynamic content

This may be a dumb question, so my apologies if so; I'm fairly new to Android.
But anyway - I have a working ViewStub, which is replaced by different layouts depending different situations. It's working fine with regards to showing the correct layout when I call the setLayoutResource() method, and then setVisibility to VISIBLE. However, I now need some of the content in this view that is being shows to be dynamic (i.e. I need to set it via code rather than just show a static layout).
Is this even possible? The setLayoutResource() method only takes a static layout-resource ID, but I need that layout XML file to be able to have it's TextViews contain non-static text that comes from some code that I have ready to utilize. How should this be approached if possible? I understand the concept of having a Java class, and inflating the XML to attach itself to it to update the fields, but I can't see how that relates to my code at hand, since it's simply a layout resource int I need to set for the setLayoutResource() method in ViewStub.
I can post existing code if needed, but I'm not sure it do much more than clutter up the post. For reference - All I have is a simple layout XML file with some TextViews, and then my main XML containing the ViewStub, which is part of a custom Dialog. The user is able to instantiate the Dialog and set the layout, which in turn sets the layout of the ViewStub. This is the layout in which I need the dynamic content to be used.
Any advice would be greatly appreciated. Thanks!
Turns out this wasn't too difficult to accomplish. I just needed to use the ID of the TextView layouts after inflating the ViewStub to get a copy of the actual TextViews, then I was easily able to set their text to whatever kind of dynamic/custom text I desired.
I also needed to comment out the code that shows it via the .VISIBLE call, and instead do the following (the .inflate() line of code accomplishes the same thing as setting it to VISIBLE):
View inflatedView = dialog.myStubView.inflate();
TextView myTextView = (TextView) inflatedView.findViewById(R.id.my_text_view);
myTextView.setText("Dynamic/Custom Text");

Creating xml template for feed/list items in Android?

I'm helping a friend create an android app that will have screens with lists of info similar to a feed. I've been learning xml layout in Android and have some of the basics down, but don't have a lot of familiarity with doing the java stuff. I've successfully created includes to seperate layout files for compontents within a screen, but what I'm wondering is if such a component can be used as a kind of template for feed/list items that get inserted programmatically on the back end. IE, is there a way to have Android create a list and for each list item it uses the external xml as a template? Sorry if this is somewhat vague, I'm new to this and trying to understand what our options are. TIA!
Yes, every list item can be a custom layout. In fact you always have to define a layout for the list entries. You can either choose a prebuilt one from android.R.layout or you can use your own from R.layout. You can specify it when you create the list adapter in code.
Have a look at one of the ArrayAdapter constructors for example:
public ArrayAdapter (Context context, int resource, int
textViewResourceId)
Since: API Level 1 Constructor Parameters
context - the current context.
resource - The resource ID for a layout file containing a
layout to use when instantiating views.
textViewResourceId - The id of the TextView within the layout resource to be populated
The constructor takes a layout that will be used for the ListView childs. Works similar with other adapters.
What you usually do is inflating the layout inside getView() of the adapter though. When you did that, fill all the data you need into the views of the layout, and return the view.
Note that you get an argument called convertView. This is one of the older layouts you already inflated before. In most cases the user just scrolled down and that entry is not visible anymore. If this convertView is not null, you can fill your data in there instead of inflating the whole layout again (thats expensive).
You can find a working example inside the
ANDROID_SDK\samples\android-10\ApiDemos\src\com\example\android\apis\view\List5.java file. Also take a look at the other list examples in that folder.

Custom layout in android

i've developed an android messaging app but, i would like to change the whole layout. It even includes a alert dialog which also i want to change.. help please..
Your layout is generally in an xml file, e.g., main.xml, called with something like setContentView(R.layout.main). The main.xml file is usually in /res/layouts, and can be edited directly, independent of the Java code.
you can define custom layout in xml files and call the layout inflator service to inflate that xml file.
If you want to customize alertdialog, then do the following
make a customized xml file and declare a view.set the setContentView method and use that xml file.
Then inflate the layout using the LAYOUT_INFLATER_SERVICE, thenthere is a method Alertdialog.setview(view)..use that view in it.

Categories