Android 10.0 Launcher3拖拽图标进入hotseat自适应布局功能实现一

1.前言

在10.0的系统rom定制化开发中,在对于launcher3的一些开发定制中,在对hotseat的一些开发中,需要实现动态hotseat居中
的功能,就是在拖拽图标进入和拖出hotseat,都可以保持hotseat居中的功能,接下来分析下相关功能实现
具体如图:


2.Launcher3拖拽图标进入hotseat自适应布局功能实现一的核心类

packages\apps\Launcher3\src\com\android\launcher3\Hotseat.java

3.Launcher3拖拽图标进入hotseat自适应布局功能实现一的核心功能分析和实现

Launcher顾名思义,就是桌面的意思,也是android系统启动后第一个启动的应用程序,
:Launcher3负责管理和展示用户手机桌面上的各个应用程序图标。它通过GridView或者LinearLayout等布局管理器将
图标进行排列,并支持滑动、放大缩小等手势操作
Hotseat也是属于在导航栏底部的BubbleTextView的布局,只是不显示app图标

3.1 Hotseat.java相关添加背景功能分析

在实现Launcher3拖拽图标进入hotseat自适应布局功能实现一的核心功能中,通过上述的分析得知,
首选需要给Hotseat添加背景功能,然后需要根据hotseat的数量多少来设置hotseat的宽度高度等
相关参数,这样就实现了第一步的hotseat的居中显示功能,

public class Hotseat extends CellLayout implements LogContainerProvider, Insettable, Transposable {

    @ViewDebug.ExportedProperty(category = "launcher")
    public boolean mHasVerticalHotseat;
    private final HotseatController mController;

    public Hotseat(Context context) {
        this(context, null);
    }

    public Hotseat(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public Hotseat(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        mController = LauncherAppMonitor.getInstance(context).getHotseatController();
		
    }

    public HotseatController getController() {
        return mController;
    }

    /* Get the orientation specific coordinates given an invariant order in the hotseat. */
    public int getCellXFromOrder(int rank) {
        return mHasVerticalHotseat ? 0 : rank;
    }

    public int getCellYFromOrder(int rank) {
        return mHasVerticalHotseat ? (getCountY() - (rank + 1)) : 0;
    }

    public void resetLayout(boolean hasVerticalHotseat) {
        removeAllViewsInLayout();
        mHasVerticalHotseat = hasVerticalHotseat;
        InvariantDeviceProfile idp = mActivity.getDeviceProfile().inv;
        if (hasVerticalHotseat) {
            setGridSize(1, idp.numHotseatIcons);
        } else {
            setGridSize(idp.numHotseatIcons, 1);
        }
       //add core start
       // 添加背景
      if(idp.numHotseatIcons>0){
         setBackgroundResource(R.drawable.shape_corner);
      }
       //add core end
    }

    @Override
    public void fillInLogContainerData(View v, ItemInfo info, Target target, Target targetParent) {
        target.gridX = info.cellX;
        target.gridY = info.cellY;
        targetParent.containerType = LauncherLogProto.ContainerType.HOTSEAT;
    }

    @Override
    public void setInsets(Rect insets) {
        FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) getLayoutParams();
        DeviceProfile grid = mActivity.getWallpaperDeviceProfile();
        insets = grid.getInsets();

        if (grid.isVerticalBarLayout()) {
            lp.height = ViewGroup.LayoutParams.WRAP_CONTENT;
            if (grid.isSeascape()) {
                lp.gravity = Gravity.LEFT;
                lp.width = grid.hotseatBarSizePx + insets.left;
            } else {
                lp.gravity = Gravity.RIGHT;
                lp.width = grid.hotseatBarSizePx + insets.right;
            }
        } else {
              lp.gravity = Gravity.BOTTOM;
              lp.width = ViewGroup.LayoutParams.MATCH_PARENT;
              lp.height = grid.hotseatBarSizePx + insets.bottom;
        }
        Rect padding = grid.getHotseatLayoutPadding();
        setPadding(padding.left, padding.top, padding.right, padding.bottom);
        
        setLayoutParams(lp);
        InsettableFrameLayout.dispatchInsets(this, insets);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        // Don't let if follow through to workspace
        return true;
    }

    @Override
    public RotationMode getRotationMode() {
        return Launcher.getLauncher(getContext()).getRotationMode();
    }
}

在实现Launcher3拖拽图标进入hotseat自适应布局功能实现一的核心功能中,通过上述的分析得知,
在Hotseat中相关源码分析,可以发现由
resetLayout 就是负责布局的 当hotseat 增加减少时都会重新布局
所以在setBackgroundResource(R.drawable.shape_corner);添加背景就可以了

  public void resetLayout(boolean hasVerticalHotseat) {
        removeAllViewsInLayout();
        mHasVerticalHotseat = hasVerticalHotseat;
        InvariantDeviceProfile idp = mActivity.getDeviceProfile().inv;
        if (hasVerticalHotseat) {
            setGridSize(1, idp.numHotseatIcons);
        } else {
            setGridSize(idp.numHotseatIcons, 1);
        }
       // 添加背景
        if(idp.numHotseatIcons>0){
         setBackgroundResource(R.drawable.shape_corner);
      }
    }

shape_corner.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <!--背景颜色-->
    <solid android:color="#FFFAFA" />
    <!--角的半径-->
    <corners android:radius="10dp"/>
    <!--边框颜色-->
    <stroke android:width="1dp" android:color="#00000000" />
</shape>


 public void setInsets(Rect insets) {
        FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) getLayoutParams();
        DeviceProfile grid = mActivity.getWallpaperDeviceProfile();
        insets = grid.getInsets();
        //竖屏布局
        if (grid.isVerticalBarLayout()) {
            lp.height = ViewGroup.LayoutParams.WRAP_CONTENT;
            if (grid.isSeascape()) {
                lp.gravity = Gravity.LEFT;
                lp.width = grid.hotseatBarSizePx + insets.left;
            } else {
                lp.gravity = Gravity.RIGHT;
                lp.width = grid.hotseatBarSizePx + insets.right;
            }
        } else {
            //modify core start
           // 横屏布局
           // 平板开发项目 固定横屏,所以要在这里设置参数
           // 设置宽高  左边底部的间距
             InvariantDeviceProfile idp = mActivity.getDeviceProfile().inv;
             int hotseatNums = idp.numHotseatIcons;
             lp.width = hotseatNums*grid.hotseatBarSizePx+(hotseatNums+1)*dip2px(15.0f);
             lp.height = grid.hotseatBarSizePx + insets.bottom;
             if(getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT){
                lp.leftMargin = (int)((1080-lp.width)/2);
             }else{
	lp.leftMargin = (int)((1920-lp.width)/2);
             }
            lp.gravity = Gravity.BOTTOM;
            //modify core end
        }
        Rect padding = grid.getHotseatLayoutPadding();
        // 设置padding 布局
           setPadding(0, padding.top, 0,0);
        
        setLayoutParams(lp);
        InsettableFrameLayout.dispatchInsets(this, insets);
    }

在实现Launcher3拖拽图标进入hotseat自适应布局功能实现一的核心功能中,通过上述的分析得知,
在Hotseat中相关源码分析,
而setInset() 负责设置绘制布局 的参数 这里设置hotseat的宽高等参数布局
其实只需要修改lp的参数就行了 然后hotseat 会根据长宽等参数 来具体布局每一个hotseat的具体坐标
根据横竖屏来确定lp.leftMargin的值,就可以保证居中显示

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-18 21:00:03       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-18 21:00:03       72 阅读
  3. 在Django里面运行非项目文件

    2024-07-18 21:00:03       58 阅读
  4. Python语言-面向对象

    2024-07-18 21:00:03       69 阅读

热门阅读

  1. Linux中的文件夹作用

    2024-07-18 21:00:03       22 阅读
  2. 子树的重心

    2024-07-18 21:00:03       23 阅读
  3. 网站流量统计分析工具之plausible.io

    2024-07-18 21:00:03       23 阅读
  4. 设计模式--享元模式

    2024-07-18 21:00:03       22 阅读
  5. ReferenceEquals

    2024-07-18 21:00:03       24 阅读
  6. 2024国家护网面试小结

    2024-07-18 21:00:03       21 阅读
  7. 数据结构第28节 字典树

    2024-07-18 21:00:03       20 阅读
  8. 详解深度学习中的epochs

    2024-07-18 21:00:03       23 阅读
  9. 梧桐数据库: 数据库技术中的重写子查询技术

    2024-07-18 21:00:03       23 阅读