选择微调器时,从TextInputLayout中移除焦点

时间:2018-01-30 14:57:12

标签: android android-layout focus

我有两个TextInputLayouts和一个Spinner的布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="test.focustest.MainActivity">

    <android.support.design.widget.TextInputLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <android.support.design.widget.TextInputEditText
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="I don't like"/>

    </android.support.design.widget.TextInputLayout>

    <android.support.design.widget.TextInputLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <android.support.design.widget.TextInputEditText
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="My favourite"/>

    </android.support.design.widget.TextInputLayout>

    <Spinner
        android:id="@+id/planets_spinner"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"></Spinner>

</LinearLayout>

以下是活动的代码:

 public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Spinner spinner = (Spinner) findViewById(R.id.planets_spinner);
        ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,
                R.array.planets_array, android.R.layout.simple_spinner_item);
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        spinner.setAdapter(adapter);
    }
}

当我在两个TextInputLayouts之间切换时,焦点按预期工作: 当选择第一个EditText时,它就是它的外观:

First focused

当选择第二个EditText时,这就是它的外观:

Second selected

但是当我选择微调器时,最后选择的TextInputLayout仍然是聚焦的: enter image description here

我想在Spinner打开时从两个TextInputLayouts中删除焦点。任何想法如何实现这一目标?

1 个答案:

答案 0 :(得分:0)

我设法在这篇文章的帮助下解决了这个问题:Link to post

我添加了一个自定义Spinner,它会在微调器打开时通知我的活动清除焦点。这是代码:

    public class CustomSpinner extends AppCompatSpinner {

    public interface OnSpinnerEventsListener {
        void onSpinnerOpened(AppCompatSpinner spinner);
        void onSpinnerClosed(AppCompatSpinner spinner);
    }

    public CustomSpinner(Context context) {
        super(context);
    }

    public CustomSpinner(Context context, int mode) {
        super(context, mode);
    }

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

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

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

    public CustomSpinner(Context context, AttributeSet attrs, int defStyleAttr, int mode, Resources.Theme popupTheme) {
        super(context, attrs, defStyleAttr, mode, popupTheme);
    }


    private OnSpinnerEventsListener mListener;
    private boolean mOpenInitiated = false;

    // implement the Spinner constructors that you need

    @Override
    public boolean performClick() {
        // register that the Spinner was opened so we have a status
        // indicator for when the container holding this Spinner may lose focus
        mOpenInitiated = true;
        if (mListener != null) {
            mListener.onSpinnerOpened(this);
        }
        return super.performClick();
    }

    public void setSpinnerEventsListener(
            OnSpinnerEventsListener onSpinnerEventsListener) {
        mListener = onSpinnerEventsListener;
    }

    public void performClosedEvent() {
        mOpenInitiated = false;
        if (mListener != null) {
            mListener.onSpinnerClosed(this);
        }
    }

    public boolean hasBeenOpened() {
        return mOpenInitiated;
    }

    public void onWindowFocusChanged (boolean hasFocus) {
        if (hasBeenOpened() && hasFocus) {
            performClosedEvent();
        }
    }
}

然后活动实现了这个界面:

public class MainActivity extends AppCompatActivity implements CustomSpinner.OnSpinnerEventsListener {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    final CustomSpinner spinner = (CustomSpinner) findViewById(R.id.planets_spinner);
    ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,
            R.array.planets_array, android.R.layout.simple_spinner_item);
    adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    spinner.setAdapter(adapter);
    findViewById(R.id.root).clearFocus();
    spinner.setSpinnerEventsListener(this);
}

    @Override
    public void onSpinnerOpened(AppCompatSpinner spinner) {
        View view = this.getCurrentFocus();
        if (view != null) {
            InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
            imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
        }
        findViewById(R.id.root).clearFocus();
    }

    @Override
    public void onSpinnerClosed(AppCompatSpinner spinner) {

    }
}

我还在根LinearLayout:root中添加了一个id。所以我能够清除焦点。