Do not center Placeholder in TextInputLayout vertically - material-components-android

I am using Material Components 1.1.0. On a TextInputLayout I removed the background and left-aligned the placeholder and text by setting the paddingStart of the EditText to zero.
This gives me the following result:
Note the large distance between the Placeholder and the bottom line.
When actually typing text, the distance between the text and the bottom line is much smaller:
I want the Placeholder to have the same distance from the bottom line as the real text. How can I do this?
Used style:
<style name="AppTheme" parent="Theme.MaterialComponents.Light">
<item name="textInputStyle">#style/textInputLayout</item>
</style>
<style name="textInputLayout" parent="Widget.MaterialComponents.TextInputLayout.FilledBox.Dense">
<item name="boxBackgroundColor">#color/transparentWhite</item>
</style>
Used TextInputLayout:
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/textInputLayout"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/spacing_normal"
app:layout_constraintEnd_toStartOf="#+id/guideline_end"
app:layout_constraintStart_toStartOf="#+id/guideline_start"
app:layout_constraintTop_toTopOf="parent">
<com.google.android.material.textfield.TextInputEditText
android:id="#+id/text_contract_partner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Stackoverflow"
android:paddingStart="0dp"
android:paddingEnd="0dp"
/>
</com.google.android.material.textfield.TextInputLayout>

You can extend the component and write your own behaviour. #Gabriele Mariotti is a grand master in Material Design, and I think, he is right. You can ask for this feature.
This is a bit ugly solution, it has no animation due to toggling between hints.
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/textInputLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/spacing_normal"
app:hintTextAppearance="#android:style/TextAppearance.Medium"
app:layout_constraintEnd_toStartOf="#+id/guideline_end"
app:layout_constraintStart_toStartOf="#+id/guideline_start"
app:layout_constraintTop_toTopOf="parent"
android:hint="Stackoverflow"
app:hintEnabled="false"
>
<com.google.android.material.textfield.TextInputEditText
android:id="#+id/text_contract_partner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Stackoverflow"
/>
</com.google.android.material.textfield.TextInputLayout>
text_contract_partner.setOnFocusChangeListener { v, hasFocus ->
if (hasFocus) {
textInputLayout.isHintEnabled = true
} else {
if (text_contract_partner.text.toString().isEmpty()) {
textInputLayout.isHintEnabled = false
}
}
}
1) Unfocused state with empty text:
2) Focused state with empty text:
3) Focused state with text:
4) Unfocused state with text:

Related

radautocomplete menu pops open when navigating with bottom navigation

I have a radautocomplete in one of my pages and I'm using bottom-navigation in my app.
The first time I navigate to that page is fine, but after that, when I navigate to that page, the suggestions menu automatically pops open as if I had typed something in the autocomplete but I have not. I even put a textfields above that in my form to steal the focus but that didn't make things any better.
Here is a playground sample
In case playground breaks in the future:
App.vue
<template>
<Page actionBarHidden="true">
<BottomNavigation :selectedIndex="activePage">
<TabStrip>
<TabStripItem>
<label text="0" />
</TabStripItem>
<TabStripItem>
<label text="1" />
</TabStripItem>
</TabStrip>
<TabContentItem>
<button text="go to 1" #tap="activePage=1" />
</TabContentItem>
<TabContentItem>
<StackLayout>
<TextField v-model="textFieldValue" hint="Enter text..."
backgroundColor="lightgray" />
<RadAutoCompleteTextView ref="autocomplete"
:items="choices" backgroundColor="lightgray"
completionMode="Contains" returnKeyType="done"
width="100%" borderRadius="5" />
</StackLayout>
</TabContentItem>
</BottomNavigation>
</Page>
</template>
<script>
import {
ObservableArray
} from "tns-core-modules/data/observable-array";
import {
TokenModel
} from "nativescript-ui-autocomplete";
export default {
data() {
return {
textFieldValue: "",
choices: new ObservableArray(
["one", "two", "three"].map(r => new TokenModel(r))
),
activePage: 0
};
}
};
</script>
<style scoped>
TabContentItem>* {
font-size: 30;
text-align: center;
vertical-align: center;
}
</style>
app.js
import Vue from 'nativescript-vue';
import App from './components/App';
import RadAutoComplete from 'nativescript-ui-autocomplete/vue';
Vue.use(RadAutoComplete);
new Vue({ render: h => h('frame', [h(App)]) }).$start();
I guess the issue is specific to Android, iOS seem to work fine. You may raise an issue at Github, meanwhile a possible workaround is to set visibility on suggestion view on unloaded event, toggle it back on textChanged event.
Updated Playground Sample 1
Update
Changing visibility seems to hide the suggestion view but still occupy the same so components below auto complete field becomes inaccessible. I believe setSuggestionViewHeight(...) may solve this.
Updated Playground Sample 2

Force view to redraw after setting platform specific attributes

I have the following hack that draws drop shadows for the various elements that I have:
<template>
<Page>
<TabView>
<TabViewItem title="Tab 1">
<StackLayout #loaded="addShadow">
<Label text="This box does have a shadow." />
</StackLayout>
</TabViewItem>
<TabViewItem title="Tab 2">
<StackLayout>
<Label text="This box doesn't have a shadow." />
</StackLayout>
</TabViewItem>
</TabView>
</Page>
</template>
<script>
export default {
methods: {
addShadow(event) {
if (event.object.ios) {
event.object.ios.layer.masksToBounds = false;
event.object.ios.layer.shadowOpacity = 0.5;
event.object.ios.layer.shadowRadius = 5.0;
event.object.ios.layer.shadowColor = new Color('#000000').ios.CGColor;
event.object.ios.layer.shadowOffset = CGSizeMake(0.0, 2.0);
}
}
}
}
</script>
<style scoped>
StackLayout {
background: #ffffff;
padding: 16;
margin: 16;
}
</style>
However, while the shadow looks perfect, it does not initially appear when the tab is first accessed. I have to first visit the second tab, and only after returning to the first tab, does the drop shadow get drawn.
I assume this is because I need to invoke something to redraw the layer after adding the shadow, but I cannot figure out how to do that. I've tried event.object.ios.layer.setNeedsDisplay() but it has no effect.
How can I ensure the shadow displays on the first tab render?

Nativescript – center horizontal text inside textView, dynamic text and multiline

I've got a nativescript app. I have a situation were I need to display text dynamically, so I don't know how much text and how much lines it will be.
The text need to wrap over multi lines and has to be aligned in center horizontally (not vertically, simply same distance to left and right) always.
Therefore I guess <Label> isn't the right element, because it is not for multiline (if I got this right?!).
So I choose <TextView>, but here the styles text-align: center got ignored.
So in documentation I found constructor textAlignment https://docs.nativescript.org/api-reference/modules/_ui_text_base_#textalignment, but I don't get it to work.
Doesn't work:
<TextView text="{{ taskString }}"
horizontalAlignment="center"
editable="false"
></TextView>
Doesn't work:
<TextView text="{{ taskString }}"
textAlignment="center"
editable="false"
></TextView>
Please let me know, what obvious I didn't get here. Thx.
Upate:
Label with textWrap="true" normally works just fine. But I have a "complex" <ContentView> <FlexboxLayout> combination, that seems to cause the problem with the height of Label that doesn't get updated.
Solution in my case:
Just don't use a <FlexboxLayout> <FlexboxLayout> ... </FlexboxLayout> </FlexboxLayout>solution. That won't calculate the height of Label dynamically.
Nativescript Playground:
https://play.nativescript.org/?template=play-ng&id=SnNmkQ
Label can be multiline if you enable textWrap
XML
<Label text="{{ taskString }}" textWrap="true" ...
Or
CSS
Label {
white-space: normal;
}

Android NavigationView : not show full item and not truncate

Problem : NavigationView not show full text of menu item, also not truncate text.
This item I see correctly - two words "Small title":
<item
android:id="#+id/example1"
android:icon="#drawable/filter_2"
android:title="Small title"
android:checked="false"
app:actionLayout="#layout/menu_counter" />
/>
And with next item - I see only first two words "Small title" without any truncate of next word "andveryverylongword":
<item
android:id="#+id/example2"
android:icon="#drawable/filter_2"
android:title="Small title andveryverylongword"
android:checked="false"
app:actionLayout="#layout/menu_counter" />
/>
Widget :
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
ndroid:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="#layout/nav_header_main"
app:menu="#menu/activity_main_drawer"/>
Also : AndroidStudio 1.5, support library.
EDITED :
Here is example of standart project "Navigation Drawer Activity" in Android Studio.
activity_main_drawer.xml :
in mobile :
I just got this working
* Override design_navigation_item.xml and change it to use
android:layout_height="wrap_content"
android:minHeight="?android:listPreferredItemHeightSmall"
Override design_navigation_menu_item.xml to use maxLines=2
Kinda cool, I can't believe that works. Thanks to the guy on stackoverflow that talked about overriding icon size, which helped me thinking in this direction.
Add app:itemMaxLines="2" in NavigationView of your layout.
That worked for me.
<com.google.android.material.navigation.NavigationView
android:id="#+id/navigation_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="end"
app:itemMaxLines="2"
android:background="#color/background_color"
app:headerLayout="#layout/nav_header_main"
app:menu="#menu/activity_main_drawer" />

Appcelerator alloy views slide

I am using the Alloy MVC framework over Titanium and want to make a slideshow between views. When I swipe on the screen, I want to display the next/previous view with a slide effect from right to left or left to right.
I am using this code:
A tab in my index.xml:
<Tab title="Bilan" icon="KS_nav_ui.png">
<Window title="Bilan" id="bilanTab" onSwipe="doBilanSwipe">
</Window>
</Tab>
The question view dynamically added and filled inside bilanTab:
<Alloy>
<Collection src="ReponsePossible">
<View id="questionContainer" class="container">
<Label id="questionText" />
<Button id="buttonNextQuestion">Question suivante</Button>
</View>
</Alloy>
and my two functions (3 with prevQuestion not printed here) inside index.js controller:
var previousQuestion;
var nextQuestion;
function doBilanSwipe(e){
if (e.direction == 'left'){
nextQuestion();
}
else if (e.direction == 'right'){
prevQuestion();
}
}
function nextQuestion(){
if (questionsCurrentIndex < questions.length-1){
questionsCurrentIndex++;
$.previous = previousQuestion;
$.next = Alloy.createController('question', questions.at(questionsCurrentIndex));
nextQuestion = $.next;
$.next.questionContainer.left = 320;
$.bilanTab.add($.next.questionContainer);
$.next.questionContainer.animate({left:0, duration:200});
$.previous.questionContainer.animate({left:-320, duration:200},function(){
$.previous = previousQuestion;
$.next = nextQuestion;
$.bilanTab.remove($.previous.questionContainer);
previousQuestion = $.next;
$.previous.destroy();
});
}
}
My problem is that first animation (first view moving to the left) is ok but after that, the next view just appear without any animation.
Could someone help? Thanks!
There is already the Titanium.UI.ScrollableView that does this exact thing, for all platforms.
Use it in Alloy like this:
<Alloy>
<Window id="win">
<ScrollableView id="scrollableView" showPagingControl="true">
<View id="view1" backgroundColor="#123" />
<View id="view2" backgroundColor="#246" />
<View id="view3" backgroundColor="#48b" />
</ScrollableView>
</Window>
</Alloy>
You can dynamically add views to it inside the controller like this:
$.scrollableView.addView(Ti.UI.createView({ // your custom attributes here});

Resources