Inflating all layouts from res-folder - android

There are 100+ layouts in a resource folder on android, I can go through them one by one and look at the preview in android studio. They all utilise code like:
tools:text="text for preview"
tools:visibility="visible"
Is there a way to inflate all those one after another in a list/linear layout? And upgrade the tools:xyz attribute to be shown as the real android:xyz attribute in this view
Context&Purpose: To show them in the app under a debug menu dedicated specifically to show available layouts. This is to communicate with both other developers and people without android studio.
I want to avoid doing it manually as it needs to be maintained and that can end very badly for debug functionality such as this. (And that it is a lot of layouts does not help either of course)
After writing it down it feels unlikely, but maybe someone out there have a nice angle on this?

Depending on the complexity of each layout, inflating a hundred of them at once could be quite taxing. You may run out of memory, or get a fair bit of jank. If you are OK with this, then I would say try using the include tag in your debug screen layout
A simple/naive implementation would be something like
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include layout="#layout/A"/>
<include layout="#layout/B"/>
<include layout="#layout/C"/>
<include layout="#layout/D"/>
...
</LinearLayout>
I probably wouldn't recommend doing this, but it might get the job done.
As far as the second part of your question, using tools values as actual values, I don't think there is a way to accomplish this. In fact the tools values are not even available during run time as they are stripped out during the build process.

Related

What is the ButtonBarLayout and how should we use it?

When I developed, I found a new widget called android.support.v7.widget.ButtonBarLayout unexpectedly. I tried to search it on the internet, but nothing was found, even on the official development documents site.
In the meantime, I found two ButtonBarLayout when I search ButtonBarLayout everywhere in Android Studio, one is android.support.v7.widget.ButtonBarLayout and the other is com.android.internal.widget.ButtonBarLayout. I tried to read source codes of both, I found that they are the same except package name. So I thought maybe android.support.v7.widget.ButtonBarLayout came from com.android.internal.widget.ButtonBarLayout after the internal ButtonBarLayout was through tests and released. At the same time, ButtonBarLayout is inherited from LinearLayout.
But there are some question:
What can we get from ButtonBarLayout literally and how should we use it?
I noticed the variable of private boolean mAllowStacking. When it changes, orientation of this layout would be changed. But I didn't really understand what it is used for.
So does somebody know ButtonBarLayout well?
P.S.: I used Android Studio of 2.0.0 Preview 4 and Gradle Plugin of 2.0.0-alpha3 and Android Support Library of 23.1.1 and Platform-tools of 23.1 and Build-tools of 23.0.2.
As others pointed out, the class description tells exactly what it is: an extension of LinearLayout that automatically switches to vertical orientation when it can't fit its child views horizontally.
I might add that this was clearly done to fit with the material design specifications about dialogs. They make a distinction between side by side buttons and stacked buttons. See for example:
Side-by-side buttons are recommended when the text of each label does
not exceed the maximum button width, such as the commonly used
OK/Cancel buttons.
While you should go for stacked buttons when the single button is too large, or there's not enough room for both:
When text labels exceed the maximum button width, use stacked buttons
to accommodate the text. Affirmative actions are stacked above
dismissive actions.
So, one possible use of this class, is when designing your own dialogs. For example, AlertDialog and AlertDialog.Builder offer internal support for dialogs with buttons, but sometimes you just want to subclass DialogFragment or AppCompatDialogFragment for a better control.
There, it might be useful to setup a bottom button bar that follows the design guidelines, and have full control on the buttons (like enabling and disabling, things you can't do with an AlertDialog AFAIK).
The source code describes ButtonBarLayout as follows:
/**
* An extension of LinearLayout that automatically switches to vertical
* orientation when it can't fit its child views horizontally.
*/
So, in essence, it is nothing but a smart LinearLayout which manages auto-switching orientations based on available space on screen.
The same ButtonBarLayout.java file describes mAllowStacking in comments as follows:
/** Whether the current configuration allows stacking. */
Source Code Here
You are right first of all. ButtonBar layout does not seem to be featured anywhere in the official Android documentation. I tried myself to search about it, but to no avail. However I have found some information which defines what is a ButtonBar layout and when to use it. Hopefully this will help you.
Most tutorials use the Buttonbar layout in a dialogbox or at the bottom of a screen to confirm or decline an option. The image below is a visual representation of how the ButtonBar layout has been used in a screen.
The screenshot above has the following layout xml:
<LinearLayout
style="?android:attr/buttonBarStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<Button
android:id="#+id/Button01"
style="?android:attr/buttonBarButtonStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Show" />
<Button
android:id="#+id/Button02"
style="?android:attr/buttonBarButtonStyle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Change" />
</LinearLayout>
<EditText
android:id="#+id/myView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10" >
<requestFocus />
</EditText>
So essentially what Android is doing here is simply creating two buttons next to each other in a LinearLayout with each button having the match_parent parameter set to the width. Hence each button takes half the size of the screen. Android have actually taken away the hassle of creating seperate buttons and positioning them correctly to fit different screens, by creating a simple widget handling this altogether.
As with the support library, Android have implemented this for developers using an earlier API. It is normal for them to use the support library for this purpose.
Hope this helps :)
https://android.googlesource.com/platform/frameworks/base/+/master/core/java/com/android/internal/widget/ButtonBarLayout.java
Looking into the code, I think it's a LinearLayout for buttons (duh). You can probably look at it like the Dialog buttons divided by a vertical spacer: | . AllowStacking will change the orientation to vertical and the gravity to the right instead of bottom. I should try it out to give a better answer
ButtonBarlayout is not featured anywhere in the official Android documentation.
it is used for auto-switching orientations according to the space.
Regarding your question:
How should we use it?
I guess it is undocumented because it is not stable yet.
It just popped up because this long lasting complaint originate from poor ROM modification by device vendor.
https://code.google.com/p/android/issues/detail?id=78377
See #270 for the resolution regarding classpath and why all classes inside .internal. were made public.
And nope even that fix a lot of bugs from poor ROM modification are still out there (in lots of device of well known brands). The issue is soon declined by project member.
I don't think we should use it just yet until the document show up.
Just my $.02 though.
Just to add to the other answers, if you guys want to check the orientation of a ButtonBarLayout you should check the orienation AFTER the value has called on measure.
In other words (Kotlin):
buttonBarLayout.post {
val orientation = buttonBarLayout.orientation
val height = buttonBarLayout.measuredHeight
}

Hide myactivity.xml has more than 80 views, bad for performance

Is it possible to hide this in XML file:
myactivity.xml has more than 80 views, bad for performance ?
I have a complicated UI. So, I want to hide this warning. I mean no way to switch UI into ListView, etc.
I think the issue here is the layering. If it has to layer 80 views on top of one another, that is really bad. Otherwise, that is a LOT to manage
You can see just how bad your UI performance is by using the Android tools in Developer Options > Debug GPU overdraw (on) and Show Surface updates to On. That will show you the performance issues.
Now to fix them, custom view XML'scontaining your subviews are the way to go.
Code maintainability is really important here. Right now a single one line change can screw up everything whereas with custom loaded subviews you minimize this greatly and ask a bit less of the OS at the onset potentially.
You can hide/ignore it by adding tools:ignore="TooManyViews" to the view that is making that error. For example:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
...
</LinearLayout>
will be
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
tools:ignore="TooManyViews">
...
</LinearLayout>
Note that this just hides the Lint warning and doesn't do anything else.

Displaying a TextView immediately after another

I am a first time developer for Android, so you can say I've been learning as I was developing. For most of my code that doesn't have to do with the XML layout, I had no problem patching my rookie mistakes. With that said, my rookie mistakes has caught up to me in regards to two TextViews when I initially designed them with the GUI interface designer (my major rookie mistake).
My display_city tv and display_today_date tv seem to have a symbiotic relationship with each other. Removal of either one would crash the app. They seem so dependent on each other that changing each other's positioning is impossible (at least from the myriad of things I have tried such as setting layout margins).
<TextView
android:id="#+id/display_city"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="20dip"
android:layout_above="#+id/display_today_date"
android:layout_below="#+id/get_data"
android:layout_centerHorizontal="true"
android:gravity="center_horizontal" />
<TextView
android:id="#+id/display_today_date"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_below="#+id/display_pollen_type"/>
My question is - how do I simply position display_today_date immediately after my display_city? When I first started this Android app, I relied a lot on the GUI builder. That was my first rookie mistake, which resulted in this symbiotic relationship I explained.
Currently this is what my app looks like:
I have tried changing display_today_date's layout to android:layout_below="#+id/display_city. This results in a crash. I checked logcat, but it did not give me relevant information to the reason of the crash within the XML file.
P.S. get_data is my TextEdit box.
You already have the city to show above the date with the line android:layout_above="#+id/display_today_date". You can't have 2 views in a relative layout each reference the other, or it won't be able to figure out what to do. If you don't want to put the city above the date, delete that line then add the code to place it where you want.
You could use a LinearLayout with the orientation set to horizontal. That way there is no reference to another view. So if you delete one the other one won't cause the app to crash.

How do I setup my fragments such that the layout I am using for phone also works well with tablets?

I am using my app currently ,made of fragments , just on phone. I am planning to add tablet version of the same , but seems like some fragments don't work exactly as expected on the tablet and often many mess up on landscape.So I just needed some pointers how to go about the same?
Here is my code for one of the fragments layout in xml :
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/altercolor2" >
<HorizontalPageView
android:id="#+id/headline_gallery"
android:layout_width="match_parent"
android:layout_height="140dp" />
<include layout="#layout/loading_no_results" />
</FrameLayout>
How do I alter it such that the height even works on tablet as expected without cutting off some data? Also, should i add another duplicate layout somewhere for this or there's way around it? Any help appreciated,thanks!
Try this. Make a new layout-xlarge folder in /res directory and place all your tablet related xml files in that folder. Android system automatically fetches layout files from this layout-xlarge folder for 7-10 inch screens.
And to support landscape mode, design your layout files specifically for landscape mode and put it in layout-land folder. But make sure that the name of the files in all the folders are same.
Android Training guide covers this best.
You should read it
http://developer.android.com/guide/practices/screens_support.html#support
Theory, logic and best practices are a bit long to be explained here. So, my suggestion is to read this tutorial from the official documentation, http://developer.android.com/training/basics/fragments/index.html, checking all the topics and the links suggested by Google.
Also check the example application provided by them as well.
Having done that, if you have a more specific issue, please ask here and we will be more than happy to help you.
Try putting your main views i.e HorizontalPageView in a linear layout and make use of the weight and orientation attributes of the linear layout.
As I understand from your code you want to align the views vertically, in this case the "weight" attribute does wonders
first you need to figure out whether you will use a different ui for tablet version besides the phone version, if you use the same ui disign, (one pane or two panes), just thinking about portrait/landscape is enough, otherwise you need use style and value-swxxx to arrange the layout files for tablet and phone.
Besides the phone/tablet issue, you also need use layout-land to define the same layout unit for the landscape mode. so there are (phone-portrait, phone-landscape, tablet-portrait, tablet-landscape) four scenarios.

Missing or Incorrect images and backgrounds randomly throughout app lifecycle

I was hoping someone here might have an idea what causes this sort of behaviour:
Throughout my application, in seemingly random places and in random conditions I'm observing this strange UI issue. Images are on occasion being loaded black (with the correct bounds) or with the incorrect image source (again, with the correct bounds). This effects ImageViews and has effected android:background tags with references to colour resources.
My application relies on 6 library projects, it runs Native Code via a Service and Activities in the App use GlSurfaceViews (although, not all Activities which display the problem contain OpenGL components). The problem could I suppose be from any of these places or a combination of them through using large amounts of memory.
You can see this behaviour in the following screen shots:
This is actually a 6 or so pixel wide column separator image which has been incorrectly drawn into my ImageView (the ImageView seems to have correctly sized itself).
When going out of the Application and then back in again (repeatedly) it instead appeared (and remained) like so:
After a Force Clear and a Clear App Data it returned to the correct format:
As you can also see the Magnifying Glass image next to it is displaying fine in each of these. The problems with these missing/incorrect images and backgrounds seems to happen randomly, throughout the application lifecycle, and I've been unable to find a way of reproducing it.
The layouts for these images are nothing special, I'm not doing anything funny during the rendering lifecycle (i'm not overriding onDraw() or onMeasure() or the like). The source of these images aren't being set dynamically but via the XML.
As you can see from the above example, it's not a build issue as it occurs between app lifecycles not between installs. It's also happening on different devices, Samsung 8.9, Acer Iconia Tab, Motarola XOOM,
It seems to me to be some sort of error with the reference table, could it perhaps have been nudged by my native code? Or is it an effect of me in some stages of the application using too much memory?
Here's the XML source for the above example:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/browseProgressWrapper"
android:layout_width="match_parent"
android:layout_height="#dimen/actionbar_compat_height"
android:orientation="horizontal">
<RelativeLayout android:layout_width="#dimen/search_bar_width"
android:layout_height="match_parent">
<EditText android:id="#+id/browseFilter"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="4dp"
android:layout_marginLeft="5dp"
android:imeOptions="actionSearch"
android:background="#drawable/edit_text_blue"
android:maxLength="30"/>
<ImageView android:id="#+id/clearSearch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:src="#drawable/ic_input_delete"
android:layout_marginRight="5dp"/>
</RelativeLayout>
<ImageView android:id="#+id/browseFilterButton"
android:src="#drawable/ic_menu_search"
android:scaleType="center"
android:layout_width="#dimen/actionbar_compat_height"
android:layout_height="#dimen/actionbar_compat_height"
android:layout_gravity="center_vertical"
android:minWidth="#dimen/actionbar_compat_height"/>
</LinearLayout>
A more full description of the code / layout surrounding another such occurrence I happened to get the screenshot for:
I have a "Settings" Activity which restarts my app after saving new settings details. It does this by stopping a Service, calling a new Activity (the Splash Activity) and finishing itself:
mConfiguration.save();
mConfiguration = new Configuration(Configuration.getInstance());
getActivity().stopService(new Intent(getActivity(), NativeService.class));
getActivity().finish();
startActivity(new Intent(getActivity(), SplashActivity.class));
Most of the time (and on most devices) this works fine, the Splash Activity contains an image which loads correctly. Sometimes though on some devices the Splash Activity loads either an incorrect resource (what my testers refer as "an upside down Nike tick") or just a blank box (as seen below). Does anyone know why?
Here is the Layout for the Splash page, as you can see it's pretty simple, no surprises:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/ContentBackgroundColor"
android:orientation="vertical" >
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="2" />
<ImageView
android:id="#+id/image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:src="#drawable/manager_android_400" />
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1" />
<ProgressBar
style="#android:style/Widget.ProgressBar.Large"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" />
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="2" />
</LinearLayout>
Theory tested and debunct:
I've theorised that this could be a processor/memory issue where the Layout isn't being drawn fully before the Splash screen exits and moves onto the next Activity so I put in this piece of code:
image = (ImageView) findViewById(R.id.image);
image.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
image.getViewTreeObserver().removeGlobalOnLayoutListener(this);
moveToStartScreen.start();
}
});
The hope was the code above would make sure the Image is definitely loaded before moving onto the Start page but seems to have had no observable effect.
Another Theory
I was also wondering if this could be being caused by the R.id / R.colour / R.drawable resources some how being currupted in program execution? Does anyone know why that might happen.
Could my native code be running rampant on some memory addresses that Android isn't correctly allocating?
Has anybody noticed this before - or perhaps know why this behaviour occurs?
Graeme, I had almost the same problem and found out that it was a reported bug of the android plattform. It was corrected in the 3.0 version I think. Which API are you compiling with? Try to build with the last available api and be sure to compile with JDK 1.6
If your problem is related to this bug, this should fix the problem.
This is a simple problem of refresh, clean, and rebuild.
Images in your various drawable folders or resource id indices are out of sequence because they were either changed outside of the eclipse IDE (via external source control such as GIT, SVN or other edits) and not refreshed in the eclipse navigator. Or, the files may have been updated in a library project upon which your UI Activity depends.
I have found that although .java file dependencies are propagated throughout the system, this is not always the case for resources such as images and .xml files.
The solution is fairly simple, clean everything, refresh all of your projects, and rebuild. The stretched or black edges should be gone.
Note: The predominant manifestation of this problem occurs when 9-patch images become treated like standard .png images. This means that they get stretched in a linear manner across the image instead of just at the edges. To me, this explains your 'Torn/Stretched' example. I have seen similar often. Another common manifestation is that text strings occasionally get displayed with the wrong resources!

Categories

Resources