Android Warning: The window is already focused, ignoring focus amplification

I need your eyes guys. I have been working with my code for a long time, and I still remain stuck like an old rack.

You see, there are many topics related to the Android alert:

W/InputMethodManagerService: Window already focused, ignoring focus gain of: com.android.internal.view.IInputMethodClient$Stub...

I read a lot, did not find anything useful, and my eyes are tired.

I am working on a spinner component whose first element is called Add new ... brings up a dialog to add another element to the list. Since I currently have two such spinners (in one exercise), I created a wrapper class for spinners that takes care of the logic, and I created a class that expands DialogFragment, since both spinners run a similar dialog with <EditText>only different names.

But in the view, only the first counter works. The second counter, when the choosig option to add a new one ... does nothing, just create the warning written above.

Fairing Wrap

It is an inner class KegAddActivity extends AppCompatActivityand looks like this:

public class ExtendableSpinner implements AdapterView.OnItemSelectedListener, View.OnTouchListener {
    private static final int ADD_NEW_ID = -1;

    private final Spinner _mSpinner;
    private final String _mTableName;
    private final int _mAddNewTitle;
    private final MatrixCursor _mAddOptionsCursor;

    private Uri _mAdapterUri;
    private SimpleCursorAdapter _mAdapter;
    private boolean _mWasTouched;

    public ExtendableSpinner(Spinner spinner, String tableName, int addNewTitle) {
        super();

        _mSpinner = spinner;
        _mTableName = tableName;
        _mAdapterUri = BeerBookUriHandler.getUri(tableName);
        _mAddNewTitle = addNewTitle;

        _mAddOptionsCursor = new MatrixCursor(new String[]{Table.COL_ID, BeerTable.COL_NAME});
        _mAddOptionsCursor.addRow(new String[]{"" + ADD_NEW_ID, getString(addNewTitle) + '\u2026'});

        _mSpinner.setOnTouchListener(this);
        _mSpinner.setOnItemSelectedListener(this);

    }

    public void setAdapterUri(Uri uri) {
        _mAdapterUri = uri;
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        _mWasTouched = true;
        return false;
    }

    @Override
    public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
        if (_mWasTouched) {
            // event fired by user
            if (id == ADD_NEW_ID) {
                Bundle args = new Bundle();
                args.putInt(AddNewDialogFragment.TITLE, _mAddNewTitle);

                _mAddNewDialogFragment = new AddNewDialogFragment();
                _mAddNewDialogFragment.setArguments(args);
                _mAddNewDialogFragment.show(getSupportFragmentManager(), _mTableName + "AddNewDialog");
            }
        } else {
            // event fired at activity start
            int selection = 0;
            if (_mAdapter.getCount() > 1) {
                selection = 1;
                Uri uri = BeerBookUriHandler.getUri(KegTable.NAME + "/last");
                Cursor cursor = getContentResolver().query(uri, new String[]{
                        _mTableName + "." + Table.COL_ID
                }, null, null, null);
                if (cursor != null && cursor.moveToFirst()) {
                    long lastUsedId = cursor.getLong(0);
                    selection = getPositionForId(lastUsedId);
                }
                cursor.close();
            }
            _mSpinner.setSelection(selection);
        }
    }

    @Override
    public void onNothingSelected(AdapterView<?> parent) {

    }

    public void populate() {
        Cursor cursor = getContentResolver().query(_mAdapterUri,
                BEER_PROJECTION, null, null, BeerTable.COL_NAME);
        Cursor extendedCursor = new MergeCursor(new Cursor[]{ _mAddOptionsCursor, cursor});

        _mAdapter = new SimpleCursorAdapter(getApplicationContext(),
                SPINNER_LAYOUT, extendedCursor, new String[] { BeerTable.COL_NAME },
                new int[] {android.R.id.text1}, 0);
        _mAdapter.setDropDownViewResource(SPINNER_ITEM_LAYOUT);
        _mSpinner.setAdapter(_mAdapter);
    }

    public int getPositionForId(long itemId) {
        int pos = 0;
        for(int i = 1, l = _mAdapter.getCount(); i < l; i++)
            if (itemId == _mAdapter.getItemId(i)) {
                pos = i;
                break;
            }

        return pos;
    }

    public long getSelectedId() {
        return _mSpinner.getSelectedItemId();
    }

    public void setSelectionById(long id) {
        _mSpinner.setSelection(getPositionForId(id));
    }
}

KegAddActivity

in onCreate()method I create spinners like this.

protected void onCreate(final Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    ...

    final Spinner beerSpinner = (Spinner) findViewById(R.id.keg_add_beer);
    _mBeerSpinner = new ExtendableSpinner(beerSpinner, BeerTable.NAME, R.string.beer_add);
    // initially disable, wait for brewery selection
    beerSpinner.setEnabled(false);

    final Spinner brewerySpinner = (Spinner) findViewById(R.id.keg_add_brewery);
    _mBrewerySpinner = new ExtendableSpinner(brewerySpinner, BreweryTable.NAME, R.string.brewery_add) {
        @Override
        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
            super.onItemSelected(parent, view, position, id);
            if (id > 0) {
                // brewery selected, populate beerSpinner
                Uri uri = BeerBookUriHandler.getUri(BreweryTable.NAME + "/" +
                        getSelectedId() + "/" + BeerTable.NAME);
                _mBeerSpinner.setAdapterUri(uri);
                _mBeerSpinner.populate();
                beerSpinner.setEnabled(true);
            }
        }
    };
    _mBrewerySpinner.populate();

    ...
}

My current suspicion

Because the first spinner works, and the second does not, and it's pretty similar, I think the spinners are suitable for focus at the same time, but I really don't know. I tried replacing the spinners event with DialogFragmenta separate action dedicated to each counter, and onItemSelectedthen it triggered startActivityForResult(), but it caused the same problem, the first spinner worked fine, and the second failed with a warning, so the problem might be in the Spinners code.

Finally, progress!

, , , , .

... , " ...", ignoring focus gain . , " ...", . , , , . , onItemSelected , . , "" AddNewDialog, , ... , AddNewDialog .

, , , , " ...", , "Spinner to default". .

Spinner , , itemSelected , W/InputMethodManagerService: Window already focused, ignoring focus gain.

Spinner onItemClick, , , . ... AddNewDialog, onDialogNegativeClick default ... item, Add new... .

+4
1

, Spinner, onItemSelected(), :

public class CustomSpinner extends Spinner {

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

        public CustomSpinner(Context contextArg, AttributeSet attributeSetArg){
            super(contextArg, attributeSetArg);
        }

        public CustomSpinner(Context contextArg, AttributeSet attributeSetArg, int styleArg){
            super(contextArg, attributeSetArg, styleArg);
        }

        @Override
        public void setSelection(int positionArg){
            boolean samePosition = positionArg == getSelectedItemPosition();
            super.setSelection(positionArg, false);
            // here we modifiy the Spinner default behavior
            if(samePosition){
                // we dispatch the event, even if the position is the same
                OnItemSelectedListener onItemSelectedListener = getOnItemSelectedListener();
                if(onItemSelectedListener != null){
                    onItemSelectedListener.onItemSelected(this,
                            getSelectedView(),
                            positionArg,
                            getSelectedItemId());
                }
            }
        }

        @Override
        public void setSelection(int positionArg, boolean animateArg){
            boolean samePosition = positionArg == getSelectedItemPosition();
            super.setSelection(positionArg, animateArg);
            // here we modifiy the Spinner default behavior
            if(samePosition){
                // we dispatch the event, even if the position is the same
                OnItemSelectedListener onItemSelectedListener = getOnItemSelectedListener();
                if(onItemSelectedListener != null){
                    onItemSelectedListener.onItemSelected(this,
                            getSelectedView(),
                            positionArg,
                            getSelectedItemId());
                }
            }
        }
}
+2

Source: https://habr.com/ru/post/1617907/


All Articles