Xamarin Android как отобразить список, если пользователь начинает печатать со специальным символом @, например, тегами WhatsApp? - PullRequest
3 голосов
/ 17 января 2020

Я хочу показать список пользователей, когда пользователь начинает печатать с помощью специального символа @, например, функций тегирования в WhatsApp.

Я использую регулярное выражение, но оно работает только для первого слова, которое не работает для вторых слов, как "Hello @ ab c и @xyz."

ниже мой код.

if (searchtext.ToString().Contains("@"))
{
   Regex regex = new Regex("@([a-zA-Z])+");
   MatchCollection matches = regex.Matches(searchtext.ToString());
   if (matches != null && matches.Count != 0)
    {
       string temptext = matches[matches.Count - 1].ToString().Substring(1);
       searchUserList = userList.Where(s=>s.userName.ToLower().StartsWith(temptext.ToString().ToLower())).ToList();

       _usersListAdapter = new TagUsersListAdapter(this.Activity, searchUserList, this);
       _lstViewUsers.SetAdapter(_usersListAdapter);

       _lstViewUsers.Visibility = ViewStates.Visible;
    }
    else
    {
        _lstViewUsers.Visibility = ViewStates.Visible;
    }

}
else
{
   _lstViewUsers.Visibility = ViewStates.Gone;

   _usersListAdapter = new TagUsersListAdapter(this.Activity, userList, this);
   _lstViewUsers.SetAdapter(_usersListAdapter);
}

Ответы [ 2 ]

2 голосов
/ 17 января 2020

Согласно вашему описанию, вы хотите найти элемент из Списка и отобразить ListView, когда пользовательский тип запуска задает c символов. Я сделал пример, который вы можете увидеть:

Main_Activity.a xml :

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" android:orientation="vertical">

<EditText
    android:layout_width="match_parent"
    android:layout_height="wrap_content" android:id="@+id/editText1"/>

 <ListView android:id="@+id/mainlistview" 
           android:layout_height="match_parent" 
           android:layout_width="match_parent" android:visibility="gone" />
</LinearLayout>

Mainactivity.cs:

 public class MainActivity : AppCompatActivity
{


    private EditText edittext;
    List<person> items;
   private ListView mainList;
    private UsersListAdapter usersListAdapter;
    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
        Xamarin.Essentials.Platform.Init(this, savedInstanceState);
        // Set our view from the "main" layout resource
        SetContentView(Resource.Layout.activity_main);

        items = new List<person>()
        {
       new person(){username="cherry",age=12 },
       new person(){username="barry",age=23},
       new person(){username="wendy",age=13},
        new person(){username="wendy2",age=13},
         new person(){username="cherry3",age=12 },
       new person(){username="barry4",age=23}
        };

        mainList = (ListView)FindViewById<ListView>(Resource.Id.mainlistview);
        //mainList.Adapter = new ArrayAdapter(this, Android.Resource.Layout.SimpleListItem1, items);

        edittext = FindViewById<EditText>(Resource.Id.editText1);
        mainList = FindViewById<ListView>(Resource.Id.mainlistview);
        edittext.TextChanged += Edittext_TextChanged;                     
    }

    private void Edittext_TextChanged(object sender, Android.Text.TextChangedEventArgs e)
    {
        if (e.Text.ToString().Contains("@"))
        {
            Regex regex = new Regex("@([a-zA-Z])+");
            MatchCollection matches = regex.Matches(e.Text.ToString());
            if (matches != null && matches.Count != 0)
            {
                int count = matches.Count;
                for (int i = 0; i < count; i++)
                {
                    string temptext = matches[i].ToString().Substring(1);

                    List<person> searchUserList = items.Where(s => s.username.ToLower().StartsWith(temptext.ToString().ToLower())).ToList();

                    mainList.Adapter = new UsersListAdapter(this, searchUserList);

                    mainList.Visibility = ViewStates.Visible;
                }
            }
            else
            {
                mainList.Visibility = ViewStates.Gone;
                mainList.Adapter = new UsersListAdapter(this, items);

            }

        }
    }

    public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
    {
        Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);

        base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
    }
}

public class person
{
    public string username { get; set; }
    public int age { get; set; }
}

Адаптер:

public class UsersListAdapter : BaseAdapter<person>
{
    List<person> items;
    Activity context;

    public UsersListAdapter(Activity context, List<person> items) : base()
    {
        this.context = context;

        this.items = items;
    }
    public override person this[int position]
    {
        get { return items[position]; }
    }

    public override int Count
    {
        get { return items.Count; }
    }


    public override long GetItemId(int position)
    {
        return position;
    }

    public override View GetView(int position, View convertView, ViewGroup parent)
    {
        var item = items[position];



        View view = convertView;

        if (view == null) // no view to re-use, create new

        view = context.LayoutInflater.Inflate(Resource.Layout.layout2, null);

        view.FindViewById<TextView>(Resource.Id.tv1).Text = item.username;

        view.FindViewById<TextView>(Resource.Id.tv2).Text = item.age.ToString();


        return view;
    }
}

Layout2.a xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent" >

<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content" 
    android:id="@+id/tv1"/>
 <TextView
android:layout_width="match_parent"
android:layout_height="wrap_content" 
    android:id="@+id/tv2" />

  </LinearLayout>

Образец в github:

https://github.com/CherryBu/searchTextSample

Скриншот:

enter image description here

Обновление:

Я обновляю некоторый код в MainActivity.cs, пожалуйста, посмотрите мой код:

public class MainActivity : AppCompatActivity
{


    private EditText edittext;
    List<person> items;
   private ListView mainList;
    private UsersListAdapter usersListAdapter;
    private person selecteditem;
    private List<person> searchUserList;
    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
        Xamarin.Essentials.Platform.Init(this, savedInstanceState);
        // Set our view from the "main" layout resource
        SetContentView(Resource.Layout.activity_main);

        items = new List<person>()
        {
       new person(){username="cherry",age=12 },
       new person(){username="barry",age=23},
       new person(){username="wendy",age=13},
        new person(){username="wendy2",age=13},
         new person(){username="cherry3",age=12 },
       new person(){username="barry4",age=23}
        };

        //mainList = (ListView)FindViewById<ListView>(Resource.Id.mainlistview);
        //mainList.Adapter = new ArrayAdapter(this, Android.Resource.Layout.SimpleListItem1, items);

        edittext = FindViewById<EditText>(Resource.Id.editText1);
        mainList = FindViewById<ListView>(Resource.Id.mainlistview);
        mainList.ItemClick += delegate (object sender, AdapterView.ItemClickEventArgs e)
        {
            if(searchUserList.Count>0)
            {
                selecteditem = searchUserList[e.Position];
                int index = edittext.Text.LastIndexOf("@");
                int count = edittext.Text.Length;

                edittext.Text = edittext.Text.Remove(index+1,count-index-1).Insert(index+1,selecteditem.username.ToString());
                //edittext.Text = edittext.Text + selecteditem.username.ToString();
                edittext.SetSelection(edittext.Text.Length);
                selecteditem = null;
                mainList.Visibility = ViewStates.Gone;
            }

        };
        edittext.TextChanged += Edittext_TextChanged;                     
    }

    private void Edittext_TextChanged(object sender, Android.Text.TextChangedEventArgs e)
    {

        if (e.Text.ToString().Length > 2 && e.Text.ToString().Substring(e.Text.ToString().Length-2, 1) =="@")
        {
            Regex regex = new Regex("@([a-zA-Z])+");
            MatchCollection matches = regex.Matches(e.Text.ToString());
            if (matches != null && matches.Count != 0)
            {
                int count = matches.Count;
                for (int i = 0; i < count; i++)
                {
                    string temptext = matches[i].ToString().Substring(1);

                     searchUserList = items.Where(s => s.username.ToLower().StartsWith(temptext.ToString().ToLower())).ToList();


                    mainList.Adapter = new UsersListAdapter(this, searchUserList);

                    mainList.Visibility = ViewStates.Visible;
                }
            }
            else
            {
                mainList.Visibility = ViewStates.Gone;
                mainList.Adapter = new UsersListAdapter(this, items);

            }



        }
    }

    public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
    {
        Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);

        base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
    }
}

Снимок экрана здесь:

enter image description here

Вот пример обновления, который вы можете посмотреть:

https://github.com/CherryBu/searchtextsample2

0 голосов
/ 17 января 2020

Я думаю, что ваше регулярное выражение должно быть @([a-zA-Z]+).

Демо: https://regex101.com/r/r676aK/1

Это демо основано на Python и использует глобальный флаг для не останавливаться на первом матче. Но для получения всех совпадений на Android Java вы можете обратиться к Как найти все совпадения с регулярным выражением в android (обратите внимание, что ответ получен в 2011 году).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...