1. ホーム
  2. アンドロイド

入力可能なドロップダウンボックスSpinnerコントロールのAndroidマニュアル実装(ツールクラス)

2022-02-28 10:14:52
<パス

I. 序文

考察

自分磨きのためのブログと、必要な人への手助けをするためのブログを、もう少し書こうと考えています。残念ながら、このプロジェクトは近すぎて、雑用が多すぎて余裕がありません、残念です。とにかく、時間を見つけては、このブログを完成させようとしています

要点をまとめると

Androidにはドロップダウンボックスのスピナーコントロールが付属していますが、ネイティブのスピナーコントロールは(私が知る限り)ユーザー入力をサポートしておらず、データリストに問題がなければ選択をサポートするだけです。そのため、手動入力が可能なドロップダウンボックスを実装するには、私たち自身で手動で実装する必要があります。
ここできっかけを与えてくれたブログに感謝したい。https://blog.csdn.net/u013700040/article/details/52914070
一般的なアイデアは、EditTextとImageViewを組み合わせてコントロールを実装し、インターフェースのポップアップにpopupWindowを使用するというものです。
PopupWindowは、ユーザーとの対話のためにandroidが使用するダイアログ・インターフェースであるという点で、AlertDialogと似ています。

第二に、入力可能なスピナーの実装

1. SpinnerPopupWindow クラスの実装

  • 役割 このクラスは、スピナーコントロールのドロップダウンボックスインターフェースを読み込むために使用され、カスタムスピナーをクリックすると、アンドロイドのネイティブスピナーのようにドロップダウンリストをポップアップ表示します。
  • コード
/*
 * @ Description:
 * @ Time: 2019/5/18 18:40:24
 * @ Author: lgy
 */
public class SpinnerPopupWindow
 extends PopupWindow {
    private List
 datas;//listview data
    private NormalAdapter adapter;
    private LayoutInflater inflater;
    private ListView mListView;
    private Context mContext; // Context parameter

    public SpinnerPopupWindow(Context context, List
 datas, AdapterView.OnItemClickListener clickListener){
        super(context);
        mContext = context;
        inflater = LayoutInflater.from(context);
        this.datas = datas;
        init(clickListener);
    }

    private void init(AdapterView.OnItemClickListener clickListener){
        View view = inflater.inflate(R.layout.spinner_window_layout, null);
        setContentView(view);
        setWidth(LinearLayout.LayoutParams.WRAP_CONTENT);
        setHeight(LinearLayout.LayoutParams.WRAP_CONTENT);
        setFocusable(true);
        ColorDrawable dw = new ColorDrawable(0x00);
        setBackgroundDrawable(dw);
        mListView = (ListView) view.findViewById(R.id.popup_listview);
        mListView.setAdapter(adapter = new NormalAdapter(mContext,datas,R.layout.spinner_popup_item));
        mListView.setOnItemClickListener(clickListener);
    }
}



  • 説明 コードは比較的単純なので、詳細は省略します。SpinnerPopupWindowをテンプレートクラスとして定義しているのは、拡張を容易にするためです。クラス定義の際に型を渡すだけです。コンストラクタのOnItemClickListenerには、ListViewの子クリックメッセージのレスポンスをコールバックの形で、アダプターの型であるAdapterView.OnItemClickListenerを渡しています。
  • インターフェースです。書いた後、そのpopupWindowが読み込むためのインターフェイス(Activityが読み込むのと同じxmlインターフェイスと同等)を手で書き、名前を: spinner_window_layoutにしてlayoutフォルダの下に置く必要があります。 インターフェースのコードには、listViewだけが含まれている必要があります。 . そのコードは以下の通りです。

  • リソースの背景。さて、round_edge_radius_tv_blリソースファイルをあげるのを忘れるところでした。このリソースファイルはListViewの背景を設定するもので、自分でデザインすることができ、次のコードが与えられています。
    ファイル名:round_edge_radius_tv_bl.xml

  • アダプターです。ListView を定義したので、リストにデータソースを提供するためのアダプタを定義する必要があります。ファイル名は NormalAdapter で、コードは以下のようになります。
/*
 * @ Description:
 * @ Time: 2019/5/21 17:00:22
 * @ Author: lgy
 */
public class NormalAdapter
 extends BaseAdapter {
    protected Context context;
    private List
 datas;
    protected LayoutInflater inflater;
    protected int layoutId;

    public NormalAdapter(Context context, List
 datas, int layoutId) {
        this.context = context;
        this.datas = datas;
        inflater = LayoutInflater.from(context);//associate layout
        this.layoutId = layoutId;
    }

    @Override
    public int getCount() {
        return datas.size();
    }

    @Override
    public Object getItem(int position) {
        return datas.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
      ViewHolder viewHolder;
        if(convertView == null){
            viewHolder = new ViewHolder();
            convertView = inflater.inflate(R.layout.spinner_popup_item,null);
            viewHolder.textTv = (TextView) convertView.findViewById(R.id.tv_item);
            convertView.setTag(viewHolder);
        }else{
            viewHolder = (ViewHolder) convertView.getTag();
        }
        viewHolder.textTv.setText(getItem(position).toString());
        return convertView;
    }

    private class ViewHolder{
        private TextView textTv;
    }

}




これでPopupWindowの実装はだいたい終わりです。popupWindowは主にListViewであるポップアップインターフェイスを定義しています。

2. スピナーツールクラスの定義

  • 役割 PopupWindowを定義した後、スピナー(ドロップダウンボックス)を定義し、スピナー上のコントロールをクリックすることでPopupWindowをポップアップさせる必要があります。Spinnerでは、EditTextとImageViewを組み合わせて使用します。では、これらは何をするのでしょうか?だいたい想像がつくと思います。
    EditTextです。ユーザーの選択データを表示し、ユーザーの入力をサポートするために使用します。
    ImageView: ユーザークリックメッセージを受信 (クリックでpopupWindowへ)

    という名前のクラス。CommonSpinner、テンプレートクラスとして定義され、簡単に拡張できる。
  • クラスコードを実装する。
/*
 * @ Description:Generic dropdown box tool class
 * @ Time: 2019/5/19 13:36:43
 * @ Author: lgy
 */
public class CommonSpinner
 extends RelativeLayout {
    private Context context;//context
    private List
 datas;//dropdown menu dataset
    private View Spinner;
    private SpinnerPopupWindow
 popupWindow;
    private RelativeLayout rl_text;
    private EditText et_text;
    private ImageView iv_text;

    private String showTitle;
    private String showText;

    //interface, message response
    private Spinner_ClickListener spinner_ClickListener;
    //used to display popupWindow
    private View.OnClickListener clickListener= new OnClickListener() {
        @Override
        public void onClick(View v) {
            switch (v.getId()) {
                case R.id.common_iv:
                    popupWindow.setWidth(rl_text.getWidth());
                    popupWindow.showAsDropDown(rl_text);
     // setTextImage(R.mipmap.arrow_down_bl);
                    break;
            }
        }
    };
    // for the child click event of the ListView in popupWindow
    private AdapterView.OnItemClickListener itemClickListener=new AdapterView.
        @Override
        public void onItemClick(AdapterView<? > parent, View view, int position, long id) {
            popupWindow.dismiss();
            et_text.setText(datas.get(position).toString());
            showText = datas.get(position).toString();
            // This interface is used to be responsible for calling other interfaces when they do click operations
            if(spinner_ClickListener ! = null){
                spinner_ClickListener.ClickListener(datas.get(position).toString());
            }
        }
    };

    public CommonSpinner(Context context, String showTitle, List
 datas) {
        super(context);
        this.context = context;
        this.showTitle = showTitle;
        this.datas=datas;
        init();
    }
    // Set the interface
    public void setSpinner_ClickListener(Spinner_ClickListener spinner_ClickListener){
        this.spinner_ClickListener = spinner_ClickListener;
    }
    private void init() {
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        Spinner = inflater.inflate(R.layout.common_spinner_layout, this);
        rl_text = (RelativeLayout)Spinner.findViewById(R.id.common_rl);
        et_text = (EditText) Spinner.findViewById(R.id.common_et);
        iv_text = (ImageView) Spinner.findViewById(R.id.common_iv);
        et_text.setText(showTitle);
        //set TextView click event
        iv_text.setOnClickListener(clickListener);
        //initialize popupWindow
        popupWindow = new SpinnerPopupWindow<>(getContext(), datas, itemClickListener);
        popupWindow.setOnDismissListener(dismissListener);
    }
    /**
     * Listen to popupwindow cancel
     */
    private PopupWindow.OnDismissListener dismissListener = new PopupWindow.OnDismissListener() {
        @Override
        public void onDismiss() {
        // setTextImage(R.mipmap.spinner_up);
        }
    };
    /**
     * Set the image to the right of the TextView
     * @param resId
     */
    private void setTextImage(int resId) {
        Drawable drawable = getResources().getDrawable(resId);
        drawable.setBounds(0, 0, drawable.getMinimumWidth(), drawable.getMinimumHeight()); // must set the image size, otherwise it will not be displayed
        et_text.setCompoundDrawables(null, null, drawable, null);
    }
    
    // used to get the value in the external TextView
    public String getText(){
        return et_text.getText().toString().trim();
    }
    /**
     * @Description: Get the EditText on the Spinner interface externally
     * @Author:lgy
     * @Date:2019/5/20 15:22
     */
    public EditText getEditView(){
        return et_text;
    }
}



説明 RelativeLayoutを継承したスピナツールクラスを定義し、common_spinner_layoutというレイアウトxmlファイルを読み込むだけです(EditTextとImageViewのみを含む)。ドロップダウンボックスツールクラスでは、コンストラクタに
OnClickListenerです。ImageView上のPopupWindowをポップアップするために使用される、コントロールのクリック応答です。
②AdapterView.OnItemClickListener.OnItemClickListener.OnItemClickListener.OnItemClickListener の略。ListView上のサブアイテムがクリックされたときに、EditTextにデータを表示するためのListView用サブアイテムクリック応答関数です。

このコードの行に着目してください。
スピナー = inflater.inflate(R.layout.common_spinner_layout, this);

これは、定義されたインターフェイスのレイアウトを定義されたツールクラス(RelativeLayout)にロードするものです。

  • インターフェースコード:common_spinner_layoutという名前のファイル

インターフェースには、EditTextと右側のImageViewだけが含まれ、ImageViewは画像を下矢印としてロードし、ドロップダウンボックスフラグを表現します。
画像リソース: arrow_down_bl (Iconfontでベクター画像を見つけ、自分で参照することができます。)

ここで、Spinnerツールクラスはラップされているので、Activityの中でそれを参照することになります。

3. 書かれている CommonSpinner クラスを参照する。

アクティビティでレイアウトを定義します。ここでは、LinearLayoutの線形レイアウトを使用します。
ここでは線形レイアウトを1つだけ定義し、このレイアウトを通して、書き込んだツールクラスCommonSpinnerをロードします。


アクティビティコードです。

        List
 data_list;
        String[] strings= getResources().getStringArray(R.array.geology_factor);
        data_list= Arrays.asList(strings);
        spinner_factor=new CommonSpinner<>(GeotechnicalDescription.this,"Please select",data_list);
        spinner_factor.setSpinner_ClickListener(new Spinner_ClickListener() {
            @Override
            public void ClickListener(String data) {
                if(data.equals(getResources().getString(R.string.DIY))){
                    spinner_factor.getEditView().setText("");
                    EditText et=spinner_factor.getEditView();
                    et.setFocusable(true);
                    et.setFocusableInTouchMode(true);
                    InputMethodManager inputManager = (InputMethodManager)et.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
                    if(inputManager!=null) {
                        et.requestFocus();
                        inputManager.showSoftInput(et, 0);
                    }
                }
            }
        });


ドロップダウンボックスのデータは、string.xmlファイルですでに定義されています: 例.

"custom"
    
al
        
al+pl
        
h
        
Custom
    

public interface Spinner_ClickListener { public void ClickListener(String data);