View-tag dosen't work - android

I have some preoblems when it comes to designing a view, As you can see I have open my xml file with a view-tag, and it gives me error. why is that? if I change it to LinearLayout than it works.
<View xmlns:android="http://schemas.android.com/apk/res/android"
class="android.app.SearchDialog$SearchBar"
android:id="#+id/search_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:focusable="true"
android:descendantFocusability="afterDescendants">
<!-- Outer layout defines the entire search bar at the top of the screen -->
<TextView
android:id="#+id/search_badge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="2dip"
android:drawablePadding="0dip"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:attr/textColorPrimaryInverse" />
<!-- Inner layout contains the app icon, button(s) and EditText -->
<LinearLayout

I don't think you can create a view like that in xml. The purpose of the xml files is to create a layout, which will be shown in your activity. Thus, the top level element needs to be one of the layout elements. See declaring layouts.

Related

How to hide layouts / views programmatically in Android

I have just started learning Android. Few confusions I have regarding layouts in XML
Are all views that I define in my layout are essentially inflated or they are optional? Suppose I have two different views in a view-group but I want to
use only first or only second conditionally. Is it possible?
How dynamically created views deal with layout.XML
file?
If I want received messages to be shown in red and sent messages in black how can I do that?
You can include views in the XML layout file that are invisible until you programatically display them. Just use "android:visible="gone" or "android:visible="invisible" in the XML file.
For instance, I include the following in my layout file initially but it's not visible:
<LinearLayout
android:id="#+id/pnlLatLong"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:visibility="gone"
>
<TextView
android:id="#+id/lblLatLng"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/lat_long"
/>
<EditText
android:id="#+id/txtLatitude"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="numberDecimal|numberSigned"
/>
<EditText
android:id="#+id/txtLongitude"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="numberDecimal|numberSigned"
/>
</LinearLayout>
In Java code, when the code logic dictates it should be visible, I change the visibility programatically to:
View v = findViewById(R.id.pnlLatLng);
v.setVisibility(View.VISIBLE);
you can set android:visibility="gone" in xml or by code setVisibility(View.gone); for change text color you can set android:text color="#000000" or by code setTextColor();

Customizing the layout of a PreferenceScreen

My requirements
Note: I need to support Android API 15 and onwards.
In my PreferenceFragment I am dynamically adding PreferenceScreen's to a PreferenceCategory.
PreferenceScreen as = mgr.createPreferenceScreen(context);
as.setTitle(name);
myCategory.addPreference(as);
When the settings Activity renders these PreferenceScreens are rendered with just a title in it's row, see the image below.
I want to customize what is shown in this row. Ideally I would like to have a title with a summary below, an icon to the left of the title/summary and on certain rows an icon on the right hand side. See the mockup image below.
PreferenceScreen.setWidgetLayoutResource(int widgetLayoutResId)
I know I can use "setWidgetLayoutResource" to add an icon to the right of the row layout (and a summary with "setSummary") using the following code in my settings activity
PreferenceScreen as = mgr.createPreferenceScreen(context);
as.setTitle(name);
as.setSummary(summary);
as.setWidgetLayoutResource(R.layout.as_widget);
myCategory.addPreference(as);
where "as_widget.xml" is
<?xml version="1.0" encoding="utf-8"?>
<ImageView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_action_favorite"/>
this will produce UI like the following
This gets me closer to what I would like but still not exactly what I would like (missing the icon at the beginning of the row).
PreferenceScreen.setLayoutResource(int layoutResId)
I believe if I use this, then I can control the rendering of the whole row. I have seen examples of this on stackoverflow, such as
Setting preference layout and changing the attribute in it
Creating a custom layout for preferences
From my understanding the layout file you specify has to have the following
its root View with the id "#android:id/widget_frame"
a view with the id android:id="#+android:id/title" (this is where the
string specified in PreferenceScreen.setTitle is placed)
a view with the id android:id="#+android:id/summary" (this is where
the string specified in PreferenceScreen.setSummary is placed)
However when I try and do this, Android Studio highlights "#+android:id/summary" with the error "Can not resolve symbol '#+android:id/summary'. When the application runs my rows are rendered completely blank.
My java is
PreferenceScreen as = mgr.createPreferenceScreen(context);
as.setTitle(name);
as.setSummary(summary);
as.setLayoutResource(R.layout.as_row_layout);
myCategory.addPreference(as);
And my layout is
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/widget_frame"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?android:attr/listPreferredItemHeight"
android:gravity="center_vertical"
android:paddingRight="?android:attr/scrollbarSize">
<ImageView
android:id="#+id/icon1"
android:src="#drawable/ic_action_email"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center" />
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="15dip"
android:layout_marginRight="6dip"
android:layout_marginTop="6dip"
android:layout_marginBottom="6dip"
android:layout_weight="1">
<TextView android:id="#+android:id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceLarge"
android:ellipsize="marquee"
android:fadingEdge="horizontal" />
<TextView android:id="#+android:id/summary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#android:id/title"
android:layout_alignLeft="#android:id/title"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:attr/textColorSecondary"
android:maxLines="4" />
</RelativeLayout>
<ImageView
android:id="#+id/icon2"
android:src="#drawable/ic_action_favorite"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center" />
</LinearLayout>
Extending PreferenceScreen
I looked at extended PreferenceScreen to overwrite how it renders, but it appears this class has now been made final so all examples on the internet that do it that way can not be used.
I have managed to get this working.
The Preference class uses com.android.internal.R.layout.preference as its layout. This contains an ImageView for an icon on the left hand side, then the title and summary textviews and finally a widget_frame Layout on the right hand side.
By calling "PreferenceScreen.setIcon(..)" you can set the drawable to place in the icon image view. By calling PreferenceScreen.setWidgetLayoutResource("...") you can set the layout to place in the widget_frame layout, in my case I put an ImageView layout containing my image.
Here is my Java code.
PreferenceScreen as = mgr.createPreferenceScreen(context);
as.setTitle(name);
as.setSummary(summary);
// add an icon to the PreferenceScreen,
// this is rendered on the left hand side of the row
accountScreen.setIcon(R.drawable.my_pref_icon);
// specify the layout to inflate into the widget area on the
// right hand side of the row, this layout is just my image
as.setWidgetLayoutResource(R.layout.as_widget);
myCategory.addPreference(as);
This produces a layout like the following
The problem with this layout is that the icons do not left align with the text of the preferences below which have no icons.
This can be resolved by specifying the layout for the PreferenceScreen as well. I copied Android's preference.xml into my project (renaming it appropriately for my usecase) and I changing the ImageView to have a left padding and margin of 0dp.
From
<ImageView
android:id="#+android:id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
/>
to
<ImageView
android:id="#+android:id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:paddingLeft="0dp"
android:layout_marginLeft="0dp"/>
I then specified my copy of preference.xml for the PreferenceScreen's layout. So my java is now
PreferenceScreen as = mgr.createPreferenceScreen(context);
as.setTitle(name);
as.setSummary(summary);
// add an icon to the PreferenceScreen,
// this is rendered on the left hand side of the row
accountScreen.setIcon(R.drawable.my_pref_icon);
// specify the layout to inflate into the widget area on the
// right hand side of the row, this layout is just my image
as.setWidgetLayoutResource(R.layout.as_widget);
// specify the layout for the preference screen row when it is
// rendered as a row in a preference activity/fragment
as.setLayoutResource(R.layout.preference_row_layout);
myCategory.addPreference(as);
I believe the reason my original attempt at using PreferenceScreen.setLayoutResource was not working was because the layout I specified was incorrect. The incorrect layout had the whole layout with an id of #android:id/widget_frame, i.e.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#android:id/widget_frame" ...>
.....
</LinearLayout>
The correct layout does not need an id for the main layout, but needs to contain child views with ids of #+android:id/icon, #+android:id/title, #+android:id/summary, #+android:id/widget_frame, i.e.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
....>
<ImageView android:id="#+android:id/icon" ....>
....
<TextView android:id="#+android:id/title" ...>
....
<TextView android:id="#+android:id/summary" ...>
....
<LinearLayout android:id="#+android:id/widget_frame" ..>
....
</LinearLayout>
You can also customise the layout of a Preference by overriding Preference.onCreateView(parent). The example below uses an anonymous inner class to make red preferences.
screen.addPreference(
new Preference(context) {
#Override
protected View onCreateView(ViewGroup parent) {
View view = super.onCreateView(parent);
view.setBackgroundColor(Color.RED);
return view;
}
});

Attach view to custom RelativeLayout in Android

I have a RelativeLayout with a match_parent main LinearLayout view and a secondary wrap_content LinearLayout which is initially not visible (gone).
The secondary one has to be shown at the top of the screen but declaring it at the beginning of the xml file, it is not shown even when set to visible because it's behind the main one.
That's why it's declared after the main LinearLayout.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:id="#+id/main_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!-- FULL SCREEN CONTENT -->
</LinearLayout>
<LinearLayout
android:id="#+id/secondary_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/f_white_transparent"
android:gravity="center"
android:visibility="gone">
<TextView
android:id="#+id/myText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="10dp" />
</LinearLayout>
</RelativeLayout>
I would like to create a custom RelativeLayout to be used in all the xml files where I can obtain the same behavior and I can be able to put whatever content under the main layout.
Is there any way to do it still using xml?
You are using a RelativeLayout but do not use the benefits of it. You can declare the wrap_content-Layout in first place and add the parameter android:layout_alignParentBottom="true" to it.
In your match_parent-LinearLayout you can add the parameter android:layout_above="#+id/secondary_layout" to make sure it will give space to the secondary Layout. This way gone will work, too.

Add drawable to EditText's top|left corner

I know that in Android we can use function setCompoundDrawables(..) to add drawable.
My problem is that my EditText is multy-lines and i want to put drawable in EditText's top|left corner. But using at setCompoundDrawables() function, only give choice to put drawable in specific side.
Is it possibility at Android API to Do it?
Seems it's impossible to do it with only EditText / TextView without anyside effect and additional views (I've provided the way at the end, but it needs more work with image and can be not applicable for every phone, because of different edit text backgorunds depending of manufature). The same question have been asked already many times: here and here for example.
Per my understanding the easiest and fastests way might be not as suggested in above questions (by usage of RelativeLayout), but just using FrameLayout the following way (You'll have 2 views vs 3 view using RelativeLayout+ImageView):
Make your icon 9patch (using 9patch tool). E.g. you have the following icon initially:
Then You can convert it to the following one:
(You can see black pixels which shows area to be stretched with view and areas for content)
Using the following xml:
<!-- Main activity layout -->
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- Edit text with drawable at top left -->
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="#drawable/icon_9patch">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/edit"
android:hint="Enter text"
android:maxLines="10"
android:inputType="textMultiLine" />
</FrameLayout>
</RelativeLayout>
Gives the following result (I've added multiple lines of text):
Moreover, it's even possible to comply the task with only EditText (but You might loose default EditText background which might not be good, however You can include it into your ning-patch image; but it will still be the same on all phones instead of native one).
The following xml also works fine:
<!-- Main activity layout -->
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- Edit text with drawable at top left -->
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/edit"
android:hint="Enter text"
android:maxLines="10"
android:inputType="textMultiLine"
android:layout_alignParentBottom="true"
android:background="#drawable/icon_9patch" />
</RelativeLayout>
Give the following result (note that default frame for edit has disappeared):
Try this one :
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/scale_10"
android:orientation="horizontal">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/map_mark"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="#dimen/scale_10"
android:gravity="top"
android:text="TEXT HERE"/>
</LinearLayout>

Crashes whenever I try to use a custom view object in XML layout

I have made myself a custom LinearLayout by the name of com.theflyingnerd.DroidMe.DiscreteNumericalRangeSelectorWidget that hosts a couple of spinner widgets. This custom LinearLayout inflates the following XML layout (You might not need to look at this too carefully but it's here for completeness):
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<!-- Min value Spinner -->
<Spinner
android:id="#+id/discrete_numerical_range_selector_min_value_spinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="left"
android:layout_weight="1" />
<TextView
android:id="#+id/to_text"
android:text="to"
android:textSize="14sp"
android:paddingLeft="10sp"
android:paddingRight="10sp"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_gravity="center"
android:layout_weight="0">
</TextView>
<!-- Max value Spinner -->
<Spinner
android:id="#+id/discrete_numerical_range_selector_max_value_spinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="right"
android:layout_weight="1" />
I have placed one such object in the layout for one of my activities like so:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<include layout="#layout/search_form_section_generic_top"/>
<include layout="#layout/search_form_section_car_specific"/>
<com.theflyingnerd.DroidMe.DiscreteNumericalRangeSelectorWidget/>
<include layout="#layout/search_form_section_advanced_options" />
</LinearLayout>
The problem is that my app force closes immediately upon startup. I've checked by putting breakpoints in my custom LinearLayout that none of my custom code is even being run yet. Furthermore, if I copy-paste the layout code for my compound widget in place everything works, which indicates to me that I probably haven't left any important XML attributes out. What could be going wrong?
I fixed it by making the LinearLayout XML element in the widget layout into a merge instead, and moved all of the layout parameters out of the widget XML file and into the activity XML itself, thus replacing
<com.theflyingnerd.DroidMe.DiscreteNumericalRangeSelectorWidget/>
with
<com.theflyingnerd.DroidMe.DiscreteNumericalRangeSelectorWidget
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
If someone could tell me why this worked, it might help me and others doing it again, and you can take credit.
because you must specify the width and height of every view you use in you xml?

Categories

Resources