12

バックグラウンド

アプリ内を移動するための新しい方法として、ナビゲーション ドロワーを使用できることは誰もが知っています (このようなライブラリを使用する場合でも)。

また、 SYSTEM_ALERT_WINDOW パーミッションを使用して、一部のアプリが他のアプリの上に浮かぶことができることもわかっています ( AirCalcで示されているよう) 。

一部のアプリでは、次のように、上にあるビューの展開と折りたたみを組み合わせていることに気付きました。

などなど...

問題

他のアプリの上にあるという 2 つの概念を統合し、ハンドルをドラッグして左側にコンテンツを表示できるようにする必要があります (ナビゲーション ドロワーなど)。

多分これは私が何を意味するかを示すかもしれません:

ここに画像の説明を入力

私の知る限り、システム アラート権限を使用して何かを一番上に置くには、ビューのサイズを知る必要があります。

ただし、ユーザーがナビゲーション ドロワーのハンドルのみを表示する場合に画面の残りの部分をブロックしたくないため、画面全体に設定できないため、これは異なります。

質問

2つのコンセプトを融合することは可能ですか?

トップにいる間、すべての状態が適切に動作できるようにするにはどうすればよいですか?

タッチのブロックを回避するために、ユーザーがハンドルを上下にドラッグしたり、何らかの方法でその位置をカスタマイズできるようにしたいと考えています。

4

4 に答える 4

7

https://github.com/NikolaDespotoski/DrawerLayoutEdgeToggleからのいくつかのアイデアに基づいて 、NavigationDrawer のハンドルのより単純なバージョンを実装しました。

次のように使用します。

View drawer = findViewById(R.id.drawer);
float verticalOffset = 0.2f;
DrawerHandle.attach(drawer, R.layout.handle, verticalOffset);

引き出しハンドル:

import android.content.Context;
import android.graphics.Point;
import android.os.Build;
import android.support.v4.view.GravityCompat;
import android.support.v4.view.ViewCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v4.widget.ViewDragHelper;
import android.view.Display;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.FrameLayout;

public class DrawerHandle implements DrawerLayout.DrawerListener {
    public static final String TAG = "DrawerHandle";

    private ViewGroup mRootView;
    private DrawerLayout mDrawerLayout;
    private View mHandle;
    private View mDrawer;

    private float mVerticalOffset;
    private int mGravity;
    private WindowManager mWM;
    private Display mDisplay;
    private Point mScreenDimensions = new Point();

    private OnClickListener mHandleClickListener = new OnClickListener(){

        @Override
        public void onClick(View v) {
            if(!mDrawerLayout.isDrawerOpen(mGravity)) mDrawerLayout.openDrawer(mGravity);
            else mDrawerLayout.closeDrawer(mGravity);
        }

    };

    private OnTouchListener mHandleTouchListener = new OnTouchListener() {
        private static final int MAX_CLICK_DURATION = 200;
        private long startClickTime;
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN: {
                    startClickTime = System.currentTimeMillis();
                    break;
                }
                case MotionEvent.ACTION_UP: {
                    if(System.currentTimeMillis() - startClickTime < MAX_CLICK_DURATION) {
                        v.performClick();
                        return true;
                    }
                }
            }
            MotionEvent copy = MotionEvent.obtain(event);
            copy.setEdgeFlags(ViewDragHelper.EDGE_ALL);
            copy.setLocation(event.getRawX() + (mGravity == Gravity.LEFT || mGravity == GravityCompat.START ? -mHandle.getWidth()/2 : mHandle.getWidth() / 2), event.getRawY());
            mDrawerLayout.onTouchEvent(copy);
            copy.recycle();
            return true;
        }
    };

    private int getDrawerViewGravity(View drawerView) {
        final int gravity = ((DrawerLayout.LayoutParams) drawerView.getLayoutParams()).gravity;
        return GravityCompat.getAbsoluteGravity(gravity, ViewCompat.getLayoutDirection(drawerView));
    }

    private float getTranslation(float slideOffset){
        return (mGravity == GravityCompat.START || mGravity == Gravity.LEFT) ? slideOffset*mDrawer.getWidth() : -slideOffset*mDrawer.getWidth();
    }

    private void updateScreenDimensions() {

        if (Build.VERSION.SDK_INT >= 13) {
            mDisplay.getSize(mScreenDimensions);
        } else {
            mScreenDimensions.x = mDisplay.getWidth();
            mScreenDimensions.y = mDisplay.getHeight();
        }
    }

    private DrawerHandle(DrawerLayout drawerLayout, View drawer, int handleLayout, float handleVerticalOffset) {
        mDrawer = drawer;
        mGravity = getDrawerViewGravity(mDrawer);
        mDrawerLayout = drawerLayout;
        mRootView = (ViewGroup)mDrawerLayout.getRootView();
        LayoutInflater inflater = (LayoutInflater) mDrawerLayout.getContext().getSystemService( Context.LAYOUT_INFLATER_SERVICE );
        mHandle = inflater.inflate(handleLayout, mRootView, false);
        mWM = (WindowManager) mDrawerLayout.getContext().getSystemService(Context.WINDOW_SERVICE);
        mDisplay = mWM.getDefaultDisplay();

        mHandle.setOnClickListener(mHandleClickListener);   
        mHandle.setOnTouchListener(mHandleTouchListener);
        mRootView.addView(mHandle, new FrameLayout.LayoutParams(mHandle.getLayoutParams().width, mHandle.getLayoutParams().height, mGravity));
        setVerticalOffset(handleVerticalOffset);
        mDrawerLayout.setDrawerListener(this);
    }

    public static DrawerHandle attach(View drawer, int handleLayout, float verticalOffset) {
        if (!(drawer.getParent() instanceof DrawerLayout)) throw new IllegalArgumentException("Argument drawer must be direct child of a DrawerLayout");
        return new DrawerHandle((DrawerLayout)drawer.getParent(), drawer, handleLayout, verticalOffset);
    }

    public static DrawerHandle attach(View drawer, int handleLayout) {
        return attach(drawer, handleLayout, 0);
    }

    @Override
    public void onDrawerClosed(View arg0) {
    }

    @Override
    public void onDrawerOpened(View arg0) {

    }

    @Override
    public void onDrawerSlide(View arg0, float slideOffset) {
        float translationX = getTranslation(slideOffset);
        mHandle.setTranslationX(translationX);
    }

    @Override
    public void onDrawerStateChanged(int arg0) {

    }

    public View getView(){
        return mHandle;
    }

    public View getDrawer() {
        return mDrawer;
    }

    public void setVerticalOffset(float offset) {
        updateScreenDimensions();
        mVerticalOffset = offset;
        mHandle.setY(mVerticalOffset*mScreenDimensions.y);
    }
}

レイアウト:

<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >        

        <RelativeLayout 
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            >

            <com.fscz.views.BounceViewPager
                android:id="@+id/content_pager"
                android:layout_width="match_parent"
                android:layout_height="match_parent" 
                android:layout_centerInParent="true"
                />

            <com.fscz.views.CirclePageIndicator
                android:id="@+id/content_indicator"
                android:layout_height="wrap_content"
                android:layout_width="wrap_content" 
                android:padding="10dp"
                android:layout_centerHorizontal="true"
                android:layout_alignParentBottom="true"
                android:layout_marginTop="100dp"
                style="@style/link"
                />

        </RelativeLayout>

    <LinearLayout
            android:id="@+id/drawer"
            android:layout_width="240dp"
            android:layout_height="match_parent"
            android:layout_gravity="right"
            android:orientation="vertical"
            android:padding="20dp"
            android:background="@color/black_transparent"
            >
            <TextView
                android:layout_width="240dp"
                android:layout_height="wrap_content"
                style="@style/text"
                android:text="@string/collections"
                android:paddingBottom="20dp"
                />
            <ListView 
                android:id="@+id/drawer_list"
                android:layout_width="240dp"
                android:layout_height="0dip"
                android:choiceMode="singleChoice"
                android:divider="@android:color/transparent"
                android:dividerHeight="0dp"
                android:layout_weight="1"
                />
    </LinearLayout>

</android.support.v4.widget.DrawerLayout>

アクティビティ:

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

    mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
    mDrawer = findViewById(R.id.drawer);
    mDrawerList = (ListView) findViewById(R.id.drawer_list);

    mDrawerList.setAdapter(new ArrayAdapter<String>(this,
            R.layout.drawer_list_item, Preferences.getKnownCollections()));
    mDrawerList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapter, View view, int pos, long id) {
                Preferences.setActiveCollection(Preferences.getKnownCollections()[pos]);
                loader.loadAll(Preferences.getKnownCollections()[pos], BrowseActivity.this);
                mDrawerLayout.closeDrawers();
            }
    });

    DrawerHandle.attach(mDrawer, R.layout.handle, 0.2f);

}
于 2014-09-08T10:21:27.727 に答える
1

このライブラリをチェックしてください!非常に単純な実装。

https://github.com/kedzie/DraggableDrawers

于 2014-08-06T20:20:23.033 に答える
0

これは API レベル 8 から機能する可能性がありView.setXます。API レベル 11 より前にはないと思います。

これをあなたの中に入れることができますOnCreate

YOU_DRAWER.setDrawerListener(this);

このメソッドをオーバーライドして、これDrawerListenerをアクティビティに実装します。

@Override
public void onDrawerSlide(View arg0, float arg1) {

    /// then arg0 is your drawer View
    /// the arg1 is your offset of the drawer in the screen

    params.leftMargin = (int) (arg0.getWidth()*arg1); 
    YOUR_VIEW.setLayoutParams(params);
}
于 2014-06-06T19:41:09.977 に答える
0

あなたがそこにたどり着いたのは非常に興味深いアイデアです。私がこれまでに理解したことから; ナビゲーション ドロワー タイプのビューを作成し、フローティング オーバーレイのように実装します。

可能です。役立つ可能性のあるリソースを見つけました。ウィンドウマネージャーを使用するか、ナビゲーションドロワービューをウィンドウマネージャー内にラップし、サービスで呼び出すことができます。また、WinodowManager を使用してユーザーのタッチ モーションを追跡します。LaoutParams.(タッチの x & y 位置を含む; onTouchListner を使用)

これは、WindowManager を使用して機能のような Facebook チャット ヘッドを作成しようとしているオープン ソース プロジェクトです。

フローティングウィンドウを作成できるAndroidライブラリもあります.先ほど指摘したアプリAirCalcなどは、このプロジェクトのカスタマイズされたバージョンを使用していると思います.

これは、このプロジェクトの簡単なデモです。ここに、プロジェクトStandOut lib projectへのリンクがあります

よろしく-サティア

于 2013-09-19T10:33:54.127 に答える