android如何移动我 AutoCompleteTextView 要拥有 Class(s) 的方法/适配器

发布时间: 2017/3/19 18:28:31
注意事项: 本文中文内容可能为机器翻译,如要查看英文原文请点击上面连接.

我试着移动我日志中的一些方法 Activity 到一个单独的类,所以它们可以被重用的其他activity。我已经不能够弄清楚,想根据我使用下面一些例子。

提前的熟练度。

LoginActivity.java:

public class LoginActivity extends FirebaseUserNet implements LoaderManager.LoaderCallbacks<Cursor> {


    public AutoCompleteTextView inputEmail;

    /**
     * Id to identity READ_CONTACTS permission request.
     */
    public static final int REQUEST_READ_CONTACTS = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

    inputEmail = (AutoCompleteTextView) findViewById(R.id.email);

    // Populate the users contacts with their given permission
        populateAutoComplete();

    }

    /**
      * TODO: Everything below here needs to be put into a separate class(s) for reuse:
      */

    public void populateAutoComplete() {
        if (!mayRequestContacts()) {
            return;
        }

        getSupportLoaderManager().initLoader(0, null, this);
    }

    public boolean mayRequestContacts() {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
            return true;
        }
        if (checkSelfPermission(READ_CONTACTS) == PackageManager.PERMISSION_GRANTED) {
            return true;
        }
        if (shouldShowRequestPermissionRationale(READ_CONTACTS)) {
            Snackbar.make(inputEmail, R.string.permission_rationale, Snackbar.LENGTH_INDEFINITE)
                    .setAction(android.R.string.ok, new View.OnClickListener() {
                        @Override
                        @TargetApi(Build.VERSION_CODES.M)
                        public void onClick(View v) {
                            requestPermissions(new String[]{READ_CONTACTS}, REQUEST_READ_CONTACTS);
                        }
                    });
        } else {
            requestPermissions(new String[]{READ_CONTACTS}, REQUEST_READ_CONTACTS);
        }
        return false;
    }

    /**
     * Callback received when a permissions request has been completed.
     */
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
                                           @NonNull int[] grantResults) {
        if (requestCode == REQUEST_READ_CONTACTS) {
            if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                populateAutoComplete();
            }
        }
    }

    public Loader<Cursor> onCreateLoader(int i, Bundle bundle) {
        return new CursorLoader(this,
                // Retrieve data rows for the device user's 'profile' contact.
                ContactsContract.Data.CONTENT_URI, ProfileQueryInterface.PROJECTION,

                // Select only email addresses.
                ContactsContract.Contacts.Data.MIMETYPE +
                        " = ?", new String[]{ContactsContract.CommonDataKinds.Email
                .CONTENT_ITEM_TYPE},

                // Show primary email addresses first. Note that there won't be
                // a primary email address if the user hasn't specified one.
                ContactsContract.Contacts.Data.IS_PRIMARY + " DESC");
    }

    public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor cursor) {
        List<String> emails = new ArrayList<>();
        cursor.moveToFirst();
        while (!cursor.isAfterLast()) {
            emails.add(cursor.getString(ProfileQueryInterface.ADDRESS));
            cursor.moveToNext();
        }

        addEmailsToAutoComplete(emails);
    }

    public void onLoaderReset(Loader<Cursor> cursorLoader) {

    }

    private void addEmailsToAutoComplete(List<String> emailAddressCollection) {
        //Create adapter to tell the AutoCompleteTextView what to show in its dropdown list.
        ArrayAdapter<String> adapter =
                new ArrayAdapter<>(LoginActivity.this,
                        android.R.layout.simple_dropdown_item_1line, emailAddressCollection);

        inputEmail.setAdapter(adapter);
    }

解决方法 1:

实际上,您可以使用 CursorAdapter 来删除所有 Loader 的东西,但不管怎么说


首先,我会提取出那"可能请求"的方法。

public interface ContactPermissionRequester {
    boolean mayRequestContacts();
}

有你 activity 实施的。

然后,这个想法是你只是想要裸骨 activity 和自包含自动完成 textview 。为此,至少需要在 ContextTextView 。Db Loader ,你也传递的。

你需要问权限在 Activity 的这些方法,我认为

  • checkSelfPermission
  • shouldShowRequestPermissionRationale
  • requestPermissions

你可以试着给出其他类 ContextCompat 而不是 Context ,看看是否您可以移动权限逻辑。

public class LoginActivity extends FirebaseUserNet implements ContactPermissionRequester {

    @Override
    public boolean mayRequestContacts() {
        ...
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, 
        @NonNull int[] grantResults) {
            ...
        }

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        inputEmail = (AutoCompleteTextView) findViewById(R.id.email);
        AutoCompleteTextViewLoader autoloader = new AutoCompleteTextViewLoader(this, 
            inputEmail, getSupportLoaderManager());
        autoloader.populate();

    }
}

几乎一切可以拖入一个新的类,并使用适当的参数 / 在必要的地方字段。Activity只是现在是 Context ,但它也实现那早些时候的界面,可以请求权限。

public class AutoCompleteTextViewLoader implements LoaderManager.LoaderCallbacks<Cursor> {

    private final Context mContext;
    private final AutoCompleteTextView inputEmail;
    private final ArrayAdapter<String> adapter;
    private final LoaderManager loaderManager

    private final List<String> emails = new ArrayList<>();

    private final ContactPermissionRequester requester;

    public AutoCompleteLoader(Context context, AutoCompleteTextView textView, LoaderManager loaderManager) {
        this.mContext = context;

        this.inputEmail = textView;
        this.adapter = new ArrayAdapter<>(mContext,
                    android.R.layout.simple_dropdown_item_1line,      
                    emails);
        this.inputEmail.setAdapter(adapter);

        // This can throw a ClassCastException
        this.mRequester = (ContactPermissionRequester) context;

        this.loaderManager = loaderManager;
    }

    public List<String> getEmails() { return emails; }

    public void populate() {
        if (requester != null && !requester.mayRequestContacts()) {
            return;
        }

        loadManager.initLoader(0, null, this);
    }

    @Override
    public Loader<Cursor> onCreateLoader(int i, Bundle bundle) {
        return new CursorLoader(mContext,
                // Retrieve data rows for the device user's 'profile' contact.
                ContactsContract.Data.CONTENT_URI, ProfileQueryInterface.PROJECTION,

                // Select only email addresses.
                ContactsContract.Contacts.Data.MIMETYPE +
                        " = ?", new String[]{ContactsContract.CommonDataKinds.Email
                .CONTENT_ITEM_TYPE},

                // Show primary email addresses first. Note that there won't be
                // a primary email address if the user hasn't specified one.
                ContactsContract.Contacts.Data.IS_PRIMARY + " DESC");
    }

    @Override
    public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor cursor) {
        // ArrayList not needed here
        cursor.moveToFirst();
        while (!cursor.isAfterLast()) {
            // Add directly to adapter
            adapter.add(cursor.getString(ProfileQueryInterface.ADDRESS));
            cursor.moveToNext();
        }
        // Separate method was pointless
    }

    @Override
    public void onLoaderReset(Loader<Cursor> cursorLoader) {

    }
}
官方微信
官方QQ群
31647020