タブレット用プログラムの書き止め

android OS & iPadOS の記録。

【kotlin】 Floating Menu 自作

2024-03-18 15:56:55 | Android studio 日記

ディレクトリの移動の前にコンテキストメニューのようなものを作る。

画像をロングプレスするとお気に入りリストにパスを登録してたんだけど、
その場所にメニューを開いて機能選択できたら色々都合が良いかなぁ。

別のフラグメントを用意するのではなく、今のフラグメントにViewをXMLに追加してON、OFFする。
台紙部分をGONEすれば、無いものとなるので楽だ。
非表示で表示場所(X,Y)を設定して表示させる。移動はさせないものとする。

問題もある。
Viewをはじめに描画構築した時は表示直後にそのViewのプロパティを参照しても正常値が戻ってこない。更新タイムラグ。

メニューの表示場所をスクリーン内に修正表示させる場合はフラグメント切り替え時のView表示初回のみ位置修正ができない。
Viewの幅と高さが0のままで本当の数値が取得できないのでメニューが右外、下外に出てしまったらスクリーン内に戻せない。

ただ、XMLでメニューの大体の大きさは推し量ることができる。
それをDimens.xml でMenuWidth、MenuHeightと登録しておく。


【fragment_main.xml】

    < LinearLayout
        android:id="@+id/menu"
        android:padding="20dp"
        省略
        >

        < TextView
            android:layout_width="@dimen/menu_width"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            省略
            />

        < TextView
            android:layout_width="@dimen/menu_width"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            省略
            />

   

android:padding と android:layout_margin でメニュー数が変わっても大体の高さを推測できる。


【Dimens.xml】
    < dimen name="menu_width">200dp</dimen>
    < dimen name="menu_height">130dp</dimen>
    < dimen name="menu_offset">40dp</dimen>


【MainFragment.kt】

class MainFragment : Fragment() {
    // 省略

    private fun initFloatingMenu() {
        val menu: LinearLayout = requireActivity().findViewById(R.id.menu)
        menu.visibility = View.GONE

        val menuTextView1: TextView = requireActivity().findViewById(R.id.menu1)
        menuTextView1.setOnClickListener(View.OnClickListener {
            //
        })

        val menuTextViewDone: TextView = requireActivity().findViewById(R.id.menuDone)
        menuTextViewDone.setOnClickListener(View.OnClickListener {
            off_FloatingMenu()
        })
    }
    private fun off_FloatingMenu() {
        val menu: LinearLayout = requireActivity().findViewById(R.id.menu)
        menu.visibility = View.GONE

        waitFlag = false
    }


    // ロングプレスのタップ位置が渡されてくる

    private fun on_FloatingMenu(px:Float, py:Float) {
        val menu: LinearLayout = requireActivity().findViewById(R.id.menu)

        val w:Float = requireContext().resources.getDimension(R.dimen.menu_width) +
                requireContext().resources.getDimension(R.dimen.menu_offset) * 2

        var x:Float = px - w * 3/4
        if ( x < 0 )
            x = 20f
        else if ( px >= ( sm!!.getScreenWidth( requireContext() ) - w * 3/4) )
             x = sm!!.getScreenWidth( requireContext() ) - w

        val h:Float = requireContext().resources.getDimension(R.dimen.menu_height)
        var y:Float = py - h + requireContext().resources.getDimension(R.dimen.menu_offset)

        if ( y < 0 )
             y = 20f
        else if ( py >= ( sm!!.getScreenHeight( requireContext() ) -
             requireContext().resources.getDimension(R.dimen.menu_offset) * 2 ) )

            y = sm!!.getScreenHeight( requireContext() ) - h -
             requireContext().resources.getDimension(R.dimen.menu_offset)

        menu.x = x
        menu.y = y

        menu.visibility = View.VISIBLE
        waitFlag = true
    }
}

タップ位置からメニューのオフセット処理をする。-dx、-dy 左上にオフセット。
これは一番下に何もせずに帰るボタンを設置。そのボタンを指の下に表示させるため。

オフセットの結果、メニューがスクリーンの外に出てしまう場合にメニューをスクリーン上に戻し表示させる修正を加える。

2回の処理の後にViewの左上の座標をX,Yに代入。

 

sm!!.getScreenWidth( Context )
Context を渡すと現在のスクリーン幅を返すメソッド。

 


  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする