Android MultiAutoCompleteTextView с настраиваемым токенизатором, например WhatsApp GroupChat

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

У меня есть поиск по многим вещам, но я нашел функцию поиска в твиттере Пример вроде твиттера,

но в этом случае, когда пользователь может написать @, всплывающее окно списка не отображается. пользователь может написать что-то после @, затем в зависимости от ввода всплывающее окно покажет результат поиска.

Я хочу показать что-то вроде этого:

Заранее спасибо.

введите здесь описание изображения


person dipali    schedule 07.11.2016    source источник
comment
stackoverflow.com/a/18486927/3850595   -  person Jordi Castilla    schedule 07.11.2016
comment
пройдите по этой ссылке, доступно множество примеров. лучший   -  person Niranj Patel    schedule 07.11.2016
comment
@NiranjPatel Я хочу добавить @ и открыть всплывающее окно пользовательского списка так же, как представление автозаполнения текста.   -  person dipali    schedule 07.11.2016
comment
@dipali попробуйте ответ Сергея Никитина и попробуйте изменить код в соответствии с вашими требованиями.   -  person Niranj Patel    schedule 07.11.2016


Ответы (3)


См. TokenAutoComplete, надеюсь, это поможет

person Sergey Nikitin    schedule 07.11.2016

Я получил решение для моего вопроса.

я создал собственное представление для мультиавтозаполнения текста и добавил метод PerformFiltering для открытия всплывающего окна после @sign.

public class KcsMultiAutoCompleteTextView extends MultiAutoCompleteTextView {
    public KcsMultiAutoCompleteTextView(Context context) {
        super(context);
    }

    public KcsMultiAutoCompleteTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public KcsMultiAutoCompleteTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void performFiltering(CharSequence text, int start, int end, int keyCode) {
        if (text.charAt(start) == '@') {
            start = start + 1;
        } else {
            text = text.subSequence(0, start);
            for (int i = start; i < end; i++) {
                text = text + "*";
            }
        }
        super.performFiltering(text, start, end, keyCode);
    }

}
person dipali    schedule 10.11.2016
comment
Привет, @dipali... можешь объяснить, как мы получаем список во время выполнения из API каждый раз, когда пишем @, используя этот пользовательский класс? - person Mohammad Misbah; 06.01.2017
comment
@MohammadMisbah просто используйте этот пользовательский класс и установите текстовое представление, после чего он выполнит фильтрацию в массиве пользовательских классов. - person dipali; 09.01.2017

Сегодня я искал это. Я использовал библиотеку android-multiautocomplete. Проверьте демонстрацию, предоставленную с библиотекой. Короче говоря, вам нужно расширить 2 класса из библиотеки: tokenFilter (описывает ваш шаблон, в данном случае символ @) и ViewBinder (для настройки строк предложений, таких как размещение изображения пользователя в определенной позиции и т. д.). Итак, для меня это TokenFilter :

import androidx.annotation.NonNull;
import ridmik.one.entities.MucOptions;
import ridmik.one.ui.components.autocomplete.filter.HandleTokenFilter;

public class MucUserTokenFilter extends HandleTokenFilter<MucOptions.User> {

  public MucUserTokenFilter() {
    this('@');
  }
  public MucUserTokenFilter(char handleChar) {
    super(handleChar);
  }

  @Override
  protected boolean matchesConstraint(@NonNull MucOptions.User user, @NonNull CharSequence constraint) {
    return user.getComparableName().toLowerCase().contains(constraint.toString().toLowerCase());
  }

  @Override
  public @NonNull CharSequence toTokenString(@NonNull MucOptions.User user) {
    return handleChar +user.getComparableName(); // Add handler at the begining! this is the trick!
  }
}

А это ViewBinder:

public class MucUserViewBinder implements AutoCompleteViewBinder<MucOptions.User> {
  public static final String TAG = MucUserViewBinder.class.getSimpleName();
  @Override
  public long getItemId(@NonNull @NotNull MucOptions.User user) {
    try{
      if(user!=null) {
        return user.userId;  // ei line e crash kore :/
      }
    }catch (Exception x) {
      Timber.tag(TAG).e("Exception "+x.getMessage());
    }


    return 0;
  }

  @Override
  public int getItemLayoutId() {
    return R.layout.simple_autocomplete_row;
  }

  @NonNull
  @NotNull
  @Override
  public AutoCompleteViewHolder getViewHolder(@NonNull @NotNull View view) {
    return new MucUserViewHolder(view);
  }

  @Override
  public void bindData(@NonNull @NotNull AutoCompleteViewHolder viewHolder, @NonNull @NotNull MucOptions.User user,
                       @Nullable @org.jetbrains.annotations.Nullable CharSequence constraint) {
    MucUserViewHolder itemViewHolder = (MucUserViewHolder) viewHolder;
    itemViewHolder.textView.setText(user.getComparableName());
    String smallAvatar = user.image + "_sm.png";
    Timber.tag(TAG).e("user.image = "+smallAvatar);
    Picasso.get().load(smallAvatar)
        .placeholder(ContextCompat.getDrawable(itemViewHolder.rootView.getContext(),
            R.drawable.ic_avatar_placeholder)).into(itemViewHolder.avatar);
  }

  static class MucUserViewHolder extends AutoCompleteViewHolder {
    public final TextView textView;
    public final CircleImageView avatar;
    public final View rootView;

    protected MucUserViewHolder(@NonNull @NotNull View view) {
      super(view);
      this.rootView = view;
      this.textView = view.findViewById(R.id.textView);
      this.avatar = view.findViewById(R.id.avatar);
    }
  }
}

После этого вы переходите к своей активности/фрагменту и делаете следующее:


private MultiAutoComplete multiAutoComplete = null; // A field in your Activity / Fragment class, initialize it to null.

void initAutoSuggestions() {
  
ArrayList<MucOptions.User> someList = getUsers(); // <--- suggestions dataset depending on your code.
        AutoCompleteTypeAdapter<MucOptions.User> nameTypeAdapter =
            AutoCompleteTypeAdapter.Build.from(new MucUserViewBinder(), new MucUserTokenFilter());


        nameTypeAdapter.setItems(someList);

        this.multiAutoComplete = new MultiAutoComplete.Builder()
            .tokenizer(new PrefixTokenizer('@'))
            .addTypeAdapter(nameTypeAdapter)
            // .delayer(constraint -> { return 10; }) // eta ki bujhi ni
            .build();
        
        this.multiAutoComplete.onViewAttached(binding.textinput); // binding.textinput is your multiAutoCompleteView 
}

Затем вызовите его внутри onCreate (для Activity) или onViewCreated (для фрагмента). Наконец, внутри onDestroy:

    @Override
    public void onDestroy() {
        super.onDestroy();
          if(multiAutoComplete!=null) {
            this.multiAutoComplete.onViewDetached(); // needed for @mention that thing
        }
}

Вы также можете посмотреть демонстрацию внутри библиотеки, чтобы увидеть другие варианты.

person Qazi Fahim Farhan    schedule 21.01.2021