Androidはドラッグ可能なサスペンションボタンコントロールを実現

3378 ワード

时には、モバイルメニューが必要です.Android自体にはこのようなコントロールはありません.弟は才能がありません.最近研究して、ネット上の資料を参考にして、自分でパッケージしました.最初のバージョンなので、バグがあるかもしれません.伝言指導を歓迎します.まず原理を簡単に説明します.ジェスチャーが動くにつれて、コントロールはある位置に移動します.キーはコントロールのonTouch方法をどのように処理するかです.ここではMotionEventの3つの状態を監視する必要があります.以下のようにします.
@Override
public boolean onTouch(View v, MotionEvent event) {
    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            //    
            break;
        case MotionEvent.ACTION_MOVE:
            //    
            break;
        case MotionEvent.ACTION_UP:
            //    
            break;
    }
    return super.onTouchEvent(event);;
}

まずジェスチャーを押すとき、開始位置を覚えます:mStartX=mLastX=(int)event.getRawX(); mStartY = mLastY = (int) event.getRawY(); 押したばかりなので、最後の座標も最初の座標と同じです.次に、MotionEvent.ACTION_MOVEイベント(ジェスチャー移動)ではメニューコントロールを移動し、コードは以下の通りである:int left,top,right,bottom;int dx = (int) event.getRawX() - mLastX;//前回moveイベント後のジェスチャー移動のx軸長int dy=(int)eventを記録する.getRawY() - mLastY;//前回moveイベントからジェスチャーで移動したy軸長left=v.getLeft()+dx;//ジェスチャー位置が変化した後もコントロールの座標if(left<0){left=0;//x軸の左側は0より小さくてはいけないコントロールがすべて表示できないか表示できない}right=left+v.getWidth()if(right>mScreenWidth){right=mScreenWidth;//x軸の右側のエッジをスクリーン幅より大きくすることはできません.防止コントロールがleft=right-v.getWidth()をすべて表示できないか、表示しないことはできません.}top = v.getTop() + dy; if(topmScreenHeight){bottom=mScreenHeight;//底部はスクリーン高さtop=bottom-v.getHeight();v.layout(left, top, right, bottom);//コントロールの位置をリセットmLastX=(int)event.getRawX();//最後のx座標mLastY=(int)eventを記録する.getRawY();//最後のy座標を記録することで、ジェスチャーの移動に伴ってコントロールが移動することができます.ここで問題があります.ホームキーを押してバックグラウンドに戻り、プログラムに入ります.コントロールは最初の位置に現れます.ジェスチャーで移動した後の最後の位置には現れません.この問題は長い間探していましたが、v.layoutメソッドで位置を設定した後、コントロールのLayoutParamのパラメータを変更しなかったためです.あなたが再び入った後、ページdrawはLayoutParamの中のパラメータに基づいて描かれています.問題が見つかった以上、簡単な処理方法はジェスチャー移動が終わったときにLayoutParamを設定することです.一般的にはmoveの中で設定する必要はありません.upの方法で処理すればいいので、MotionEventで処理する必要があります.ACTION_UPには、v.setLayoutParams(createLayoutParams(v.getLeft()、v.getTop()、0,0);実はcreateLayoutParamsの方法はコントロールのLayoutParamを作成することで、以下の通りです:private FrameLayout.LayoutParams createLayoutParams(int left, int top, int right, int bottom) { FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(mBuilder.size, mBuilder.size); layoutParams.setMargins(left, top, right, bottom); return layoutParams; } これで、基本的には主な機能を実現するところではありませんが、このコントロールにクリックイベントを追加するとしたら?実際には、指の移動距離がデータより小さい場合、ジェスチャーイベントを消費しないでください.この場合、oncllickイベントがトリガーされますが、指の移動距離がデータより大きい場合、ジェスチャーイベントが消費されます.この場合、onclickはトリガーされません.コードは以下の通りです:v.setLayoutParams(createLayoutParams(v.getLeft()、v.getTop()、0,0);//ここでLayoutParamsを設定する必要があります.そうしないとhomeを押してからページに戻ってviewを待つと元の場所に戻ります.float endX=event.getRawX(); float endY = event.getRawY(); if (Math.abs(endX - mStartX) > 5 || Math.abs(endY-mStartY)>5){//クリック時の少しの移動を防ぐクリックイベントがmTouchResult=trueをブロックされました;}if(mTouchResult&&mBuilder.needNearEdge){//毎回画面の端に移動するかどうかmoveNearEdge();}最後のコードは(mTouchResultがonTouchメソッドの戻り値である)を意味し、現在はモバイルコントロールの動作を実現し、コントロールが画面のエッジを移動する必要がある場合は、コントロールを画面のエッジに移動する(これは別途実現された機能であり、ここではあまり説明しない).はい、主な原理とコードはこれらです.githubにコードを置きます.リンクは以下の通りです.https://github.com/linqssonny/DrawView上に使用方法がついています.もし皆さんが何か問題があったら、私のQ:252624617を加えて交流してください.バグがあればgithubで提出してください.私は引き続き改善します.