Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 50b04704 authored by Ben Lin's avatar Ben Lin Committed by Android (Google) Code Review
Browse files

Merge "Add focus to directory after creating them via CreateDirFragment." into nyc-andromeda-dev

parents 91057566 81afd7f5
Loading
Loading
Loading
Loading
+1 −6
Original line number Diff line number Diff line
@@ -138,6 +138,7 @@ public abstract class BaseActivity extends Activity
    abstract void refreshDirectory(int anim);
    /** Allows sub-classes to include information in a newly created State instance. */
    abstract void includeState(State initialState);
    abstract void onDirectoryCreated(DocumentInfo doc);

    public BaseActivity(@LayoutRes int layoutId, String tag) {
        mLayoutId = layoutId;
@@ -332,12 +333,6 @@ public abstract class BaseActivity extends Activity
        CreateDirectoryFragment.show(getFragmentManager());
    }

    void onDirectoryCreated(DocumentInfo doc) {
        // By default we do nothing, just let the new directory appear.
        // DocumentsActivity auto-opens directories after creating them
        // As that is more attuned to the "picker" use cases it supports.
    }

    /**
     * Returns true if a directory can be created in the current location.
     * @return
+6 −0
Original line number Diff line number Diff line
@@ -323,6 +323,12 @@ public class FilesActivity extends BaseActivity {
        }
    }

    @Override
    void onDirectoryCreated(DocumentInfo doc) {
        assert(doc.isDirectory());
        getDirectoryFragment().getFocusManager().onDirectoryCreated(doc.documentId);
    }

    @Override
    public void springOpenDirectory(DocumentInfo doc) {
        assert(doc.isContainer());
+13 −2
Original line number Diff line number Diff line
@@ -290,7 +290,14 @@ public class DirectoryFragment extends Fragment

        mRecView.setAdapter(mAdapter);

        mLayout = new GridLayoutManager(getContext(), mColumnCount);
        mLayout = new GridLayoutManager(getContext(), mColumnCount) {
            @Override
            public void onLayoutCompleted(RecyclerView.State state) {
                super.onLayoutCompleted(state);
                mFocusManager.onLayoutCompleted();
            }
        };

        SpanSizeLookup lookup = mAdapter.createSpanSizeLookup();
        if (lookup != null) {
            mLayout.setSpanSizeLookup(lookup);
@@ -310,7 +317,7 @@ public class DirectoryFragment extends Fragment
        mModel.addUpdateListener(mModelUpdateListener);

        // Make sure this is done after the RecyclerView and the Model are set up.
        mFocusManager = new FocusManager(context, mRecView, mModel);
        mFocusManager = new FocusManager(mRecView, mModel, context.getColor(R.color.accent_dark));

        final int edgeHeight = (int) getResources().getDimension(R.dimen.autoscroll_edge_height);
        GestureSelector gestureSel = GestureSelector.create(
@@ -1191,6 +1198,10 @@ public class DirectoryFragment extends Fragment
        return mModel;
    }

    public FocusManager getFocusManager() {
        return mFocusManager;
    }

    @Override
    public boolean isDocumentEnabled(String docMimeType, int docFlags) {
        return mTuner.isDocumentEnabled(docMimeType, docFlags);
+4 −0
Original line number Diff line number Diff line
@@ -38,6 +38,10 @@ interface FocusHandler extends View.OnFocusChangeListener {
    @Override
    void onFocusChange(View v, boolean hasFocus);

    void onLayoutCompleted();

    void onDirectoryCreated(String modelId);

    /**
     * Requests focus on the item that last had focus. Scrolls to that item if necessary.
     */
+44 −7
Original line number Diff line number Diff line
@@ -18,8 +18,8 @@ package com.android.documentsui.dirlist;

import static com.android.documentsui.model.DocumentInfo.getCursorString;

import android.annotation.ColorRes;
import android.annotation.Nullable;
import android.content.Context;
import android.database.Cursor;
import android.os.Handler;
import android.os.Looper;
@@ -39,7 +39,6 @@ import android.view.View;
import android.widget.TextView;

import com.android.documentsui.Events;
import com.android.documentsui.R;

import java.util.ArrayList;
import java.util.List;
@@ -49,7 +48,7 @@ import java.util.TimerTask;
/**
 * A class that handles navigation and focus within the DirectoryFragment.
 */
final class FocusManager implements FocusHandler {
public final class FocusManager implements FocusHandler {
    private static final String TAG = "FocusManager";

    private RecyclerView mView;
@@ -58,10 +57,11 @@ final class FocusManager implements FocusHandler {

    private TitleSearchHelper mSearchHelper;
    private Model mModel;
    private @Nullable String mPendingFocusId;

    private int mLastFocusPosition = RecyclerView.NO_POSITION;

    public FocusManager(Context context, RecyclerView view, Model model) {
    public FocusManager(RecyclerView view, Model model, @ColorRes int color) {
        assert (view != null);
        assert (model != null);
        mView = view;
@@ -69,7 +69,7 @@ final class FocusManager implements FocusHandler {
        mLayout = (GridLayoutManager) view.getLayoutManager();
        mModel = model;

        mSearchHelper = new TitleSearchHelper(context);
        mSearchHelper = new TitleSearchHelper(color);
    }

    @Override
@@ -126,6 +126,38 @@ final class FocusManager implements FocusHandler {
        }
    }

    /*
     * Attempts to reset focus on the item corresponding to {@code mPendingFocusId} if it exists and
     * has a valid position in the adapter. It then automatically resets {@code mPendingFocusId}.
     */
    @Override
    public void onLayoutCompleted() {
        if (mPendingFocusId == null) {
            return;
        }

        int pos = mAdapter.getModelIds().indexOf(mPendingFocusId);
        if (pos != -1) {
            focusItem(pos);
        }
        mPendingFocusId = null;
    }

    /*
     * Attempts to put focus on the document associated with the given modelId. If item does not
     * exist yet in the layout, this sets a pending modelId to be used when
     * {@code #applyPendingFocus()} is called next time.
     */
    @Override
    public void onDirectoryCreated(String modelId) {
        int pos = mAdapter.getModelIds().indexOf(modelId);
        if (pos != -1 && mView.findViewHolderForAdapterPosition(pos) != null) {
            focusItem(pos);
        } else {
            mPendingFocusId = modelId;
        }
    }

    @Override
    public int getFocusPosition() {
        return mLastFocusPosition;
@@ -267,6 +299,11 @@ final class FocusManager implements FocusHandler {
     * @param callback A callback to call after the given item has been focused.
     */
    private void focusItem(final int pos, @Nullable final FocusCallback callback) {
        if (mPendingFocusId != null) {
            Log.v(TAG, "clearing pending focus id: " + mPendingFocusId);
            mPendingFocusId = null;
        }

        // If the item is already in view, focus it; otherwise, scroll to it and focus it.
        RecyclerView.ViewHolder vh = mView.findViewHolderForAdapterPosition(pos);
        if (vh != null) {
@@ -333,8 +370,8 @@ final class FocusManager implements FocusHandler {
        private KeyEvent mLastEvent;
        private Handler mUiRunner;

        public TitleSearchHelper(Context context) {
            mSpan = new BackgroundColorSpan(context.getColor(R.color.accent_dark));
        public TitleSearchHelper(@ColorRes int color) {
            mSpan = new BackgroundColorSpan(color);
            // Handler for running things on the main UI thread. Needed for updating the UI from a
            // timer (see #activate, below).
            mUiRunner = new Handler(Looper.getMainLooper());
Loading