2017-03-16 42 views
2

Xamarin.FormsプロジェクトのAccordion ListViewで作業しています。つまり、ListViewでカテゴリ見出しをクリックすると、その下の子を展開または折りたたむことができます。Xamarin.Forms - ItemSourceを更新すると、ViewCell内の画像が点滅します。

ViewCellを使用しているので、各カテゴリ見出しに2つのイメージとタイトルがあります。問題は、カテゴリをタップして子を表示すると、カテゴリ見出しViewCellの画像が点滅することです。

アコーディオン機能を達成するために私が使用している観測可能なコレクションが2つあります。すべての親(MenuItemGroup)と子(MenuItem)の項目を含むものと、MenuItemのものだけが表示されるもの。ヘッダーがタップされるたびに、カテゴリの選択されたインデックスを取得し、それをExpandedプロパティ(子を表示または非表示)に切り替えるイベントが発生します。 DateTemplateとイメージがバインドここ

private ObservableCollection<MenuItemGroup> _allGroups; 
    private ObservableCollection<MenuItemGroup> _expandedGroups; 

    private void OnHeaderTapped(object sender, EventArgs e) 
    { 
     var selectedIndex = _expandedGroups.IndexOf(
      ((MenuItemGroup)((StackLayout)sender).Parent.BindingContext)); 

     _allGroups[selectedIndex].Expanded = !_allGroups[selectedIndex].Expanded; 

     UpdateListContent(); 
    } 

    private void UpdateListContent() 
    { 
     _expandedGroups = new ObservableCollection<MenuItemGroup>(); 

     foreach (var group in _allGroups) 
     { 
      var newGroup = new MenuItemGroup(group.Title, group.CategoryIcon, group.Expanded); 

      if (group.Count == 0) 
      { 
       newGroup.Expanded = null; 
      } 

      if (group.Expanded == true) 
      { 
       foreach (var menuItem in group) 
       { 
        newGroup.Add(menuItem); 
       } 
      } 
      _expandedGroups.Add(newGroup); 
     } 

     _menuItemListView.ItemsSource = _expandedGroups; 
    } 

です:

 var menuItemGroupTemplate = new DataTemplate(() => 
     { 
      var groupImage = new Image(); 
      groupImage.SetBinding<MenuItemGroup>(Image.SourceProperty, i => i.CategoryIcon); 

      var titleLabel = new Label 
      { 
       TextColor = Color.White, 
       VerticalTextAlignment = TextAlignment.Center, 
       VerticalOptions = LayoutOptions.Center, 
       FontSize = Device.GetNamedSize(NamedSize.Medium, typeof(Label)) 
      }; 
      titleLabel.SetBinding<MenuItemGroup>(Label.TextProperty, t => t.Title); 

      var stateIconImage = new Image 
      { 
       HorizontalOptions = LayoutOptions.EndAndExpand 
      }; 
      stateIconImage.SetBinding<MenuItemGroup>(Image.SourceProperty, i => i.IconState); 

      var menuItemGroupStackLayout = new StackLayout 
      { 
       BackgroundColor = Color.FromHex("40474d"), 
       HorizontalOptions = LayoutOptions.FillAndExpand, 
       VerticalOptions = LayoutOptions.FillAndExpand, 
       Orientation = StackOrientation.Horizontal, 
       Padding = new Thickness(10 ,0, 20, 0), 
       Children = { groupImage, titleLabel, stateIconImage } 
      }; 

      var tapGestureRecognizer = new TapGestureRecognizer(); 

      tapGestureRecognizer.Tapped += OnHeaderTapped; 
      tapGestureRecognizer.CommandParameter = menuItemGroupStackLayout.BindingContext; 
      menuItemGroupStackLayout.GestureRecognizers.Add(tapGestureRecognizer); 

      var menuItemGroupViewCell = new ViewCell 
      { 
       View = menuItemGroupStackLayout, 
       Height = 63.0 
      }; 

      return menuItemGroupViewCell; 
     }); 

     _menuItemListView = new ListView 
     { 
      RowHeight = 55, 
      IsGroupingEnabled = true, 
      ItemTemplate = menuItemTemplate, 
      GroupHeaderTemplate = menuItemGroupTemplate, 
      SeparatorColor = Color.FromHex("40474d"), 
      HasUnevenRows = true 
     }; 

groupIconstateIcon画像フラッシュの両方をリストビューItemSourceが更新されたときにその後UpdateListContent()方法は、リストビューItemSourceをリフレッシュするために呼び出されます。誰もこの問題を解決する方法の洞察を提供することはできますか?ありがとう!

あなたが役に立つと思うなら、MenuItemGroupMenuItemのクラスを投稿できます。

答えて

0

リストビューを画像で更新しようとしたときに同様の問題が発生しました。 Androidで画像のちらつきが見えました。これは通常、画像の読み込みが遅れているためです。

画像の高さと幅を固定してみてください。それでも問題が解決しない場合は、リストのコンテンツを更新する際に、必要なイメージとテキストの値のみを更新して、すべてのイメージを再度ロードする必要はありません。

洞察を必要とするだけなので、必要な場合はサンプルコードを提供できます。

だからここにあなたが何ができるかです:あなたは展開/折りたたみItemsSourceプロパティを毎回設定する必要はありませんように、_expandedGroupsであなたのListview.Itemsourceをバインド 。これはあなたのリスト、したがってあなたのイメージをリフレッシュします。

private ObservableCollection<MenuItemGroup> _expandedGroups; 
public ObservableCollection<MenuItemGroup> ExpandedGroups 
{ 
get 
{ 
    return _expandedGroups; 
} 
set 
{ 
    if(value!=null) _expandedGroups = value; 
    OnPropertyChanged("ExpandedGroups"); 
} 
} 

そして、あなたの更新用メソッドで: -

UpdateListContent(_allGroups[SelectedIndex], SelectedIndex); 
private void UpdateListContent(MenuItemGroup group, int index) 
{ 
if(group.Expanded) 
{ 
    foreach (var menuItem in group) 
    { 
    ExpandedGroup.Insert(index++, menuItem); 
    } 
} 
else 
{ 
    foreach (var menuItem in group) 
    { 
    ExpandedGroup.Remove(menuItem); //Can also use ExpandedGroup.RemoveAt(index++); 
    } 
    } 
} 

乾杯あなたallListSelectionを渡します。

+0

あなたの答えをありがとう。 'groupImage'を更新せずにlistviewを更新する方法を示すサンプルコードを提供できますか? 'groupImage'は各メニュー項目グループヘッダーで異なっていますので、SoucePropertyを束縛することは、私が各画像をどのように設定するかを知っている唯一の方法です。 – cfly24

+0

私は何ができるかの要点を与えました。必要に応じて修正し、ちらつきを防止するかどうか確認してください。 –

+0

変更するセクションのみを更新するようにコードを実装すると、小さなちらつきが残っていました。画像の幅と高さを追加すると、小さなちらつきが消えました。ありがとう! – cfly24

0

私は、Device.BeginInvokeOnMainThreadの内部にアップデートが必要であることをコントロールに通知していたコードを入れた後、驚いたことにちらちらが完全に消えてしまいました。

関連する問題