Как добавить трехуровневый ListView в ExpandableListView в xamarin android - PullRequest
0 голосов
/ 08 мая 2018

Как добавить один или несколько уровней в расширяемом списке в xamarin android. или как создать древовидное представление в xamarin android.

Я нашел решение для одного уровня ListView. Ниже мой код. Я очень плохо знаком с xamarin android. Пожалуйста помоги. Заранее спасибо.

My MainActivity.cs:

using Android.App;
using Android.OS;
using Android.Support.V7.App;
using Android.Widget;
using System.Collections.Generic;
using System;
namespace AndroidExpandableListView
{
[Activity(Label = "AndroidExpandableListView", MainLauncher = true, Icon = "@drawable/icon",
    Theme ="@style/MyTheme")]
public class MainActivity : AppCompatActivity
{
    ExpandableListViewAdapter mAdapter;
    ExpandableListView expandableListView;
    List<string> group = new List<string>();
    Dictionary<string, List<string>> dicMyMap = new Dictionary<string, List<string>>();
    protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);

        // Set our view from the "main" layout resource
        SetContentView(Resource.Layout.Main);
        var toolbar = FindViewById<Android.Support.V7.Widget.Toolbar>(Resource.Id.toolbar);
        SetSupportActionBar(toolbar);
        SupportActionBar.Title = "Expandable ListView";
        expandableListView = FindViewById<ExpandableListView>(Resource.Id.expandableListView);

        //Set Data
        SetData(out mAdapter);
        expandableListView.SetAdapter(mAdapter);

        expandableListView.ChildClick += (s, e) => {
            Toast.MakeText(this, "Clicked : " + mAdapter.GetChild(e.GroupPosition, e.ChildPosition), ToastLength.Short).Show();
        };
    }

    private void SetData(out ExpandableListViewAdapter mAdapter)
    {
        List<string> groupA = new List<string>();
        groupA.Add("A-1");
        groupA.Add("A-2");
        groupA.Add("A-3");

        List<string> groupB = new List<string>();
        groupB.Add("B-1");
        groupB.Add("B-2");
        groupB.Add("B-3");

        group.Add("Group A");
        group.Add("Group B");

        dicMyMap.Add(group[0], groupA);
        dicMyMap.Add(group[1], groupB);

        mAdapter = new ExpandableListViewAdapter(this, group, dicMyMap);
    }
}
}

Мой ExpandableListViewAdapter.cs:

namespace AndroidExpandableListView
{
public class ExpandableListViewAdapter : BaseExpandableListAdapter
{
    private Context context;
    private List<string> listGroup;
    private Dictionary<string, Dictionary<string, List<string>>> lstChild;

    public ExpandableListViewAdapter(Context context, List<string> listGroup, Dictionary<string, Dictionary<string, List<string>>> lstChild)
    {
        this.context = context;
        this.listGroup = listGroup;
        this.lstChild = lstChild;
    }

    public override int GroupCount
    {
        get
        {
            return listGroup.Count;
        }
    }

    public override bool HasStableIds
    {
        get
        {
            return false;
        }
    }

    public override Java.Lang.Object GetChild(int groupPosition, int childPosition)
    {
        var result = new List<string>();

        lstChild.TryGetValue(listGroup[groupPosition], out result);
        return 0;// result[childPosition];
    }

    public override long GetChildId(int groupPosition, int childPosition)
    {
        return childPosition;
    }

    public override int GetChildrenCount(int groupPosition)
    {
        var result = new Dictionary<string, List<string>>();
        lstChild.TryGetValue(listGroup[groupPosition], out result);
        return result.Count;
    }

    public override View GetChildView(int groupPosition, int childPosition, bool isLastChild, View convertView, ViewGroup parent)
    {
        if (convertView == null)
        {
            LayoutInflater inflater = (LayoutInflater)context.GetSystemService(Context.LayoutInflaterService);
            convertView = inflater.Inflate(Resource.Layout.item_layout, null);
        }
        TextView textViewItem = convertView.FindViewById<TextView>(Resource.Id.item);
        string content = (string)GetChild(groupPosition, childPosition);
        textViewItem.Text = content;
        return convertView;
    }

    public override Java.Lang.Object GetGroup(int groupPosition)
    {
        return listGroup[groupPosition];
    }

    public override long GetGroupId(int groupPosition)
    {
        return groupPosition;
    }

    public override View GetGroupView(int groupPosition, bool isExpanded, View convertView, ViewGroup parent)
    {
        if (convertView == null)
        {
            LayoutInflater inflater = (LayoutInflater)context.GetSystemService(Context.LayoutInflaterService);
            convertView = inflater.Inflate(Resource.Layout.group_item, null);
        }
        string textGroup = (string)GetGroup(groupPosition);
        TextView textViewGroup = convertView.FindViewById<TextView>(Resource.Id.group);
        textViewGroup.Text = textGroup;
        return convertView;
    }

    public override bool IsChildSelectable(int groupPosition, int childPosition)
    {
        return true;
    }
}

}

Я хочу разработать Listview, как показано на рисунке ниже в xamarin android. Я не уверен, реализуемо ли это с помощью Expandable Listview, потому что я пытался, и, похоже, ничего не работает. Любые ссылки будут полезны

enter image description here

1 Ответ

0 голосов
/ 18 мая 2018

Вы можете попытаться использовать OrderedDictionary для хранения данных вместо словаря, он может использовать индекс для получения значения. Например, в MainActivity:

public class MainActivity : AppCompatActivity
{
    ExpandableListViewAdapter mAdapter;
    ExpandableListView expandableListView;
    List<string> group = new List<string>();
    Dictionary<string, OrderedDictionary> dicMyMap = new Dictionary<string, OrderedDictionary>();

    protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);
        SetContentView(Resource.Layout.activity_main);
        expandableListView = FindViewById<ExpandableListView>(Resource.Id.expandableListView);
        SetData(out mAdapter);
        expandableListView.SetAdapter(mAdapter);
        expandableListView.ChildClick += (s, e) => {
            Toast.MakeText(this, "Clicked : " + mAdapter.GetChild(e.GroupPosition, e.ChildPosition), ToastLength.Short).Show();
        };
    }

    private void SetData(out ExpandableListViewAdapter mAdapter)
    {
        List<string> groupA1 = new List<string>();
        groupA1.Add("A-1-1");
        groupA1.Add("A-1-2");
        groupA1.Add("A-1-3");

        List<string> groupA2 = new List<string>();
        groupA2.Add("A-2-1");
        groupA2.Add("A-2-2");
        groupA2.Add("A-2-3");

        OrderedDictionary groupA = new OrderedDictionary();
        groupA.Add("A-1", groupA1);
        groupA.Add("A-2", groupA2);

        OrderedDictionary groupB = new OrderedDictionary();
        groupB.Add("B-1", new List<string>());
        groupB.Add("B-2", new List<string>());
        groupB.Add("B-3", new List<string>());

        group.Add("Group A");
        group.Add("Group B");

        dicMyMap.Add(group[0], groupA);
        dicMyMap.Add(group[1], groupB);

        mAdapter = new ExpandableListViewAdapter(this, group, dicMyMap);
    }
}

И вам нужно создать второй ExpandableListView в методе GetChildView() первого адаптера и установить LayoutParams. Вам также нужно установить GroupExpandListener и OnGroupCollapseListener, чтобы изменить его высоту при расширении и сворачивании. И Resource.Dimension.dimen - это высота каждого дочернего ряда. Например, ExpandableListViewAdapter:

public class ExpandableListViewAdapter : BaseExpandableListAdapter
{
    private Context context;
    private List<string> listGroup;
    private Dictionary<string, OrderedDictionary> lstChild;

    public ExpandableListViewAdapter(Context context, List<string> listGroup, Dictionary<string, OrderedDictionary> lstChild)
    {
        this.context = context;
        this.listGroup = listGroup;
        this.lstChild = lstChild;
    }

    public override int GroupCount
    {
        get
        {
            return listGroup.Count;
        }
    }

    public override bool HasStableIds
    {
        get
        {
            return true;
        }
    }

    public ExpandableListView getExpandableListView()
    {
        ExpandableListView mExpandableListView = new ExpandableListView(
                context);
        AbsListView.LayoutParams lp = new AbsListView.LayoutParams(
                ViewGroup.LayoutParams.MatchParent, (int)context
                .Resources.GetDimension(
                        Resource.Dimension.dimen));
        mExpandableListView.LayoutParameters = lp;
        mExpandableListView.DividerHeight = 0;
        mExpandableListView.SetChildDivider(null);
        mExpandableListView.SetGroupIndicator(null);
        return mExpandableListView;
    }

    public override Java.Lang.Object GetChild(int groupPosition, int childPosition)
    {
        var result = new OrderedDictionary();

        lstChild.TryGetValue(listGroup[groupPosition], out result);
        return result[childPosition].ToString();
    }

    public override long GetChildId(int groupPosition, int childPosition)
    {
        return childPosition;
    }

    public override int GetChildrenCount(int groupPosition)
    {
        var result = new OrderedDictionary();
        lstChild.TryGetValue(listGroup[groupPosition], out result);
        return result.Count;
    }

    public override View GetChildView(int groupPosition, int childPosition, bool isLastChild, View convertView, ViewGroup parent)
    {
        string group = listGroup[groupPosition];

        OrderedDictionary childData = lstChild[group];
        object[] keys = new object[childData.Keys.Count];
        childData.Keys.CopyTo(keys, 0);
        List<string> data = (List<string>)childData[childPosition];

        ExpandableListView childListView = getExpandableListView();
        SecondAdapter adapter = new SecondAdapter(context, data, keys[childPosition]);
        childListView.SetAdapter(adapter);
        childListView.SetOnGroupExpandListener(new MyOnGroupExpandListener(context, data.Count, childListView));
        childListView.SetOnGroupCollapseListener(new MyOnGroupCollapseListener(context, data.Count, childListView));

        return childListView;
    }

    public override Java.Lang.Object GetGroup(int groupPosition)
    {
        return listGroup[groupPosition];
    }

    public override long GetGroupId(int groupPosition)
    {
        return groupPosition;
    }

    public override View GetGroupView(int groupPosition, bool isExpanded, View convertView, ViewGroup parent)
    {
        if (convertView == null)
        {
            LayoutInflater inflater = (LayoutInflater)context.GetSystemService(Context.LayoutInflaterService);
            convertView = inflater.Inflate(Resource.Layout.group_item, null);
        }
        string textGroup = (string)GetGroup(groupPosition);
        TextView textViewGroup = convertView.FindViewById<TextView>(Resource.Id.group);
        textViewGroup.Text = textGroup;
        return convertView;
    }

    public override bool IsChildSelectable(int groupPosition, int childPosition)
    {
        return true;
    }
}

public class MyOnGroupExpandListener : Java.Lang.Object, IOnGroupExpandListener
{
    Context context;
    int count;
    ExpandableListView expandableListView;
    public MyOnGroupExpandListener(Context context, int count, ExpandableListView expandableListView)
    {
        this.context = context;
        this.count = count;
        this.expandableListView = expandableListView;
    }
    public void OnGroupExpand(int groupPosition)
    {
        AbsListView.LayoutParams lp = new AbsListView.LayoutParams(
        ViewGroup.LayoutParams.MatchParent,
        (int)((count + 1) * (int)context
        .Resources.GetDimension(Resource.Dimension.dimen)));
        expandableListView.LayoutParameters = lp;
    }
}


public class MyOnGroupCollapseListener : Java.Lang.Object, IOnGroupCollapseListener
{
    Context context;
    int count;
    ExpandableListView expandableListView;
    public MyOnGroupCollapseListener(Context context, int count, ExpandableListView expandableListView)
    {
        this.context = context;
        this.count = count;
        this.expandableListView = expandableListView;
    }

    public void OnGroupCollapse(int groupPosition)
    {
        AbsListView.LayoutParams lp = new AbsListView.LayoutParams(
                ViewGroup.LayoutParams.MatchParent, (int)context
                .Resources.GetDimension(Resource.Dimension.dimen));
        expandableListView.LayoutParameters = lp;
    }
}

И dimens.xml:

<resources>
  <dimen name="dimen">30dp</dimen>
</resources>

Второй адаптер прост, только основные адаптеры:

public class SecondAdapter : BaseExpandableListAdapter
{
    private Context context;
    private List<string> data;
    private object key;


    public SecondAdapter(Context context, List<string> data, object key)
    {
        this.data = data;
        this.context = context;
        this.key = key;

    }
    public override int GroupCount
    {
        get
        {
            if (data.Count == 0)
            {
                return 1;
            }
            else
            {
                return data.Count;
            }                
        }
    }

    public override bool HasStableIds
    {
        get
        {
            return true;
        }
    }

    public override View GetChildView(int groupPosition, int childPosition, bool isLastChild, View convertView, ViewGroup parent)
    {
        if (convertView == null)
        {
            LayoutInflater inflater = (LayoutInflater)context.GetSystemService(Context.LayoutInflaterService);
            convertView = inflater.Inflate(Resource.Layout.item_layout, null);
        }
        TextView textViewItem = convertView.FindViewById<TextView>(Resource.Id.item);
        textViewItem.Text = data[childPosition];
        return convertView;
    }

    public override View GetGroupView(int groupPosition, bool isExpanded, View convertView, ViewGroup parent)
    {
        if (convertView == null)
        {
            LayoutInflater inflater = (LayoutInflater)context.GetSystemService(Context.LayoutInflaterService);
            convertView = inflater.Inflate(Resource.Layout.group_item, null);
        }

        string textGroup = (string)GetGroup(groupPosition);
        TextView textViewGroup = convertView.FindViewById<TextView>(Resource.Id.group);
        textViewGroup.Text = textGroup;
        return convertView;
    }        

    public override Java.Lang.Object GetChild(int groupPosition, int childPosition)
    {
        return childPosition;
    }

    public override long GetChildId(int groupPosition, int childPosition)
    {
        return childPosition;
    }

    public override Java.Lang.Object GetGroup(int groupPosition)
    {
        return key.ToString();
    }

    public override int GetChildrenCount(int groupPosition)
    {            
        return  data.Count;
    }

    public override long GetGroupId(int groupPosition)
    {
        return groupPosition;
    }    

    public override bool IsChildSelectable(int groupPosition, int childPosition)
    {
        return true;
    }
}

group_item.axml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:minWidth="25px"
    android:minHeight="25px">
    <TextView
        android:text="Large Text"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/group" />
</LinearLayout>

item_layout.axml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:minWidth="25px"
    android:minHeight="25px">
    <TextView
        android:text="Large Text"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/item" />
</LinearLayout>

Результат:
enter image description here

...