![](/img/trans.png)
[英]Xamarin Forms Listview in StackLayout Overlapping Layout Above It
[英]Xamarin Forms Layout create overlapping views
我試圖在Xamarin.Forms
創建一個自動完成控件,到目前為止,我已經使用以下Xaml創建了ContentView
。
<ContentView.Content>
<AbsoluteLayout BackgroundColor="Red" x:Name="absLayout" HeightRequest="30">
<Entry BackgroundColor="Green" x:Name="entryView" AbsoluteLayout.LayoutBounds="1,1,1,1" AbsoluteLayout.LayoutFlags="All" Focused="Handle_Focused" Unfocused="Handle_Unfocused"/>
<ListView BackgroundColor="Blue" Margin="0,30,0,0" IsVisible="false" x:Name="listView" HeightRequest="200">
<ListView.ItemTemplate>
<DataTemplate>
<TextCell Text="{Binding .}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</AbsoluteLayout>
</ContentView.Content>
這將與其他Entry
和Label
控件一起用於ContentPage
。
當有人單擊Entry
,必須通過重疊其他控件,而不是按下其下方的其他控件,向用戶顯示在Entry
下方的相應ListView
。
我已經實現了控件的重疊,但是沒有正確完成。 ListView確實向用戶顯示列表,但其他控件將其重疊。 ListView的Z-Index較低,其他控件的Z-Index較高。
需要幫助解決此問題。
編輯1-
我想要實現的屏幕。 (這是Android中的Spinner控件)
我想對我的控件做類似的事情。
PS-請遵循此 SO答案,以找出造成此問題的根本原因。
我遇到了完全相同的問題,並使用自定義渲染器進行了修復。 這樣,用戶可以鍵入內容以過濾列表選項,然后在用戶選擇一個選項時將所選選項放在條目中。 在表單項目中,您需要一個新的條目子類:
public class AutofillTextView : Entry
{
public static BindableProperty ChoicesSourceProperty = BindableProperty.Create(
nameof(ChoicesSource), typeof(ObservableCollection<string>), typeof(CustomPicker),
default(ObservableCollection<string>), propertyChanged: OnChoicesSourceChanged);
public ObservableCollection<string> ChoicesSource
{
get { return (ObservableCollection<string>)GetValue(ChoicesSourceProperty); }
set { SetValue(ChoicesSourceProperty, value); }
}
public AutofillTextView()
{
Items = new List<string>();
}
private void ChoicesChanged(object sender, NotifyCollectionChangedEventArgs args)
{
switch (args.Action)
{
case NotifyCollectionChangedAction.Add:
Items.Add(args.NewItems[0]);
break;
default:
var itemsList = ChoicesSource.ToList();
Items = itemsList;
break;
}
OnPropertyChanged(nameof(Items));
}
private static void OnChoicesSourceChanged(BindableObject bindable, object oldValue, object newValue)
{
var textView = (AutofillTextView) bindable;
textView.ChoicesSource.CollectionChanged -= textView.ChoicesChanged;
textView.ChoicesSource.CollectionChanged += textView.ChoicesChanged;
textView.Items = newValue == null ? new List<string>() : ((ObservableCollection<string>)newValue).ToList();
}
}
您可能需要對此進行擴展,但是我從不從列表中刪除任何項目,因此切換對我來說已經足夠好了。 我還需要使用可觀察的集合,因此您可以通過切換到列表來簡化操作。 無論如何,接下來您需要在droid中使用自定義渲染器:
[assembly: ExportRenderer(typeof(AutofillTextView), typeof(AutofillTextViewRenderer))]
namespace Default
{
public class AutofillTextViewRenderer : ViewRenderer<AutofillTextView, InstantAutoCompleteTextView>
{
protected override void OnElementChanged(ElementChangedEventArgs<AutofillTextView> e)
{
base.OnElementChanged(e);
if (Control == null)
{
var control = new InstantAutoCompleteTextView(Forms.Context);
control.InputType = Android.Text.InputTypes.ClassText | Android.Text.InputTypes.TextFlagNoSuggestions;
control.Text = Element.Text;
SetNativeControl(control);
}
if (e.OldElement != null)
{
}
if (e.NewElement != null)
{
var adapter = new ArrayAdapter<string>(Forms.Context as Android.App.Activity, Resource.Layout.AutofillTextViewItem, e.NewElement.Items.ToArray<string>());
Control.Adapter = adapter;
Control.Threshold = 0;
Control.TextChanged += Control_TextChanged;
adapter.NotifyDataSetChanged();
}
}
void Control_TextChanged(object sender, Android.Text.TextChangedEventArgs e)
{
if (Element.Text != Control.Text)
{
Element.Text = Control.Text;
}
}
protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
{
base.OnElementPropertyChanged(sender, e);
if (e.PropertyName == AutofillTextView.ItemsProperty.PropertyName)
{
var adapter = new ArrayAdapter<string>(Forms.Context as Android.App.Activity, Resource.Layout.AutofillTextViewItem, Element.Items.ToArray<string>());
Control.Adapter = adapter;
adapter.NotifyDataSetChanged();
}
else if(e.PropertyName == AutofillTextView.TextProperty.PropertyName)
{
if(Control.Text != Element.Text)
{
Control.Text = Element.Text;
}
} else if(e.PropertyName == AutofillTextView.IsFocusedProperty.PropertyName) {
if(Element.IsFocused)
Control.PerformFiltering();
}
}
}
}
這會將您的自定義類(AutofillTextView)連接到android類(InstantAutoCompleteTextView),以替換默認條目渲染器。 我不使用內置的AutoCompleteTextView的原因是,在您鍵入至少一個字符之前,它不會顯示下拉菜單。 我希望重點顯示。 如果您不在乎,則可以跳過。 這是視圖:
public class InstantAutoCompleteTextView : AutoCompleteTextView
{
public InstantAutoCompleteTextView(Context context) : base(context) {}
public InstantAutoCompleteTextView(Context arg0, IAttributeSet arg1) : base(arg0, arg1){}
public InstantAutoCompleteTextView(Context arg0, IAttributeSet arg1, int arg2) : base(arg0, arg1, arg2){}
public override bool EnoughToFilter() {
return true;
}
public void PerformFiltering()
{
PerformFiltering(Text, 0);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.