Code Monkey home page Code Monkey logo

xujiaji / happybubble Goto Github PK

View Code? Open in Web Editor NEW
709.0 18.0 114.0 4.4 MB

:thought_balloon:BubbleLayout随意变化的气泡布局、消息对话框,可定制颜色,背景、弧度、尖角弧度、边框等等。BubbleDialog气泡弹窗根据点击View的位置定位它的弹窗位置,BubbleDialog可定制方向等!(BubbleLayout changes freely,BubbleDialog click on the location of View positioning its location,BubbleDialog can be customized directions.)

License: Apache License 2.0

Java 100.00%
view dialog bubble happy android android-library android-ui bubblelayout bubbledialog dialog-view

happybubble's Introduction

HappyBubble

GitHub release maven

bubble

气泡布局的形状可以改变,如四角弧度、气泡颜色、箭头大小和阴影。

气泡Dialog可以根据被点击的view的位置来确定自己展示的位置。

ENGLISH DOC

旧文档

更新

版本 更新描述 图片
1.2.6 修复列表位置偏移#43
1.2.5 修复位置偏移#36
1.2.4 修复状态栏高度获取#31
1.2.3 修复气泡内边距问题
1.2.2 新特性“设置气泡边框和边框颜色”#23 1.2.2特性
1.2.1 新特性“设置气泡背景”#25 1.2.1特性
1.2.0 箭头的上下圆弧都可以自由定制
1.1.9 修复初始位置偏移;新增通过x,y坐标显示HappyDialog
1.1.8 修复当设置透明背景时,状态栏文字颜色可能变白色问题
1.1.7 修复位置问题,修复autoPosition无效问题,修复横屏模式问题。#13#11#10
1.1.6 新增方向优先级:#9
1.1.5 修复:#8
1.1.4 ①新增方法setLayout(int width, int height, int margin),width(设置气泡的宽)、height(设置气泡的高)、margin(设置距离屏幕边缘的间距,只有当设置width或height为MATCH_PARENT才有效)。
autoPosition(true)方法准备弃用(现在还可以用),使用新方法autoPosition(Auto),如果两个都使用了会直接用autoPosition(Auto)。请参考下方“方法参考表”。
③感谢@wolf8088521提供建议#4
1.1.3 ①通过重新调用setClickedView可以直接更新当前dialog的所在位置。
②新添加setRelativeOffset(int)方法,设置dialog相对与被点击View的偏移(负值:向被点击view的中心偏移;正值:向被点击view的外侧偏移)
测试页面SetClickedViewTestActivity.java
1.1.3.gif
1.1.2 修复默认值没有适配屏幕
1.1.1 修复大小变化后,没有对应变化位置的问题;修复接触顶部偏位问题;
1.1.0 ①Dialog交互事件传递到Activity达到不在不关闭Dialog的情况下做其他Activity的操作。
②添加自动根据被点击View距离屏幕边缘的距离确定Dialog的位置。
③新增“autoPosition”和“setThroughEvent”方法,请参考“BubbleDialog方法参考表”

1.1.0.gif
1.0.3 继续优化了点击在气泡之外才会被dismiss;修复了Dialog周围会有部分点击无法dismiss;
1.0.2 修复点击dialog边缘无法取消

哪些app使用了它?

玩清单
Todo

如何开始?

在你模块中的build.gradle添加上HappyBubble依赖

repositories {
  mavenCentral()
}

dependencies {
  implementation 'com.github.xujiaji:happy-bubble:1.2.6'
}

如何使用 HappyBubble-BubbleDialog?

方法参考表(不全面) 具体详细参数请参照案例代码和attrs.xml

方法名 参数 描述
addContentView View 添加填充在气泡中的视图
setClickedView View 被点击的View(触发Dialog出现的View)
setPosition enum ...
BubbleDialog.Position:
LEFT
TOP
RIGHT
BOTTOM
BubbleDialog相对于被点击的view的位置。如果传入多个位置,那么最前面的位置优先级越高
setOffsetX int 如果您对dialog所展示的x轴位置不满,需要调整x轴方向偏移
setOffsetY int 如果您对dialog所展示的y轴位置不满,需要调整y轴方向偏移
setBubbleLayout BubbleLayout 自定义dialog的气泡布局
setTransParentBackground - 背景透明
softShowUp - 当气泡dialog中有EditText时,软键盘弹出会遮挡EditText时,dialog随软键盘上移。
show - 显示
autoPosition enum
Auto:
AROUND
UP_AND_DOWN
LEFT_AND_RIGHT
自动确定位置功能,显示在被点击View距离屏幕边缘的最大空间。开启后,“setPosition”功能失效。
AROUND:被点击View四周;
UP_AND_DOWN:被点击View上下显示;
LEFT_AND_RIGHT:被点击View左右显示;
setThroughEvent boolean, boolean 第一个参数isThroughEvent设置是否穿透Dialog手势交互。
第二个参数cancelable点击空白是否能取消Dialog,只有当"isThroughEvent=false"时才有效
setRelativeOffset int 设置dialog相对与被点击View的偏移(负值:向被点击view的中心偏移;正值:向被点击view的外侧偏移),设置后会直接影响setOffsetX和setOffsetY方法。
setLayout int,int,int 设置气泡的宽高和距离屏幕边缘的距离
第一个参数:width(设置气泡的宽);
第二个参数:height(设置气泡的高);
第三个参数:margin(设置距离屏幕边缘的间距,只有当设置width或height为MATCH_PARENT才有效)。
宽高单位为px或MATCH_PARENT

最简单的实现

exampel1 exampel2
new BubbleDialog(this)
        .addContentView(LayoutInflater.from(this).inflate(R.layout.dialog_view3, null))
        .setClickedView(mButton)
        .show();

向下偏移8dp

exampel3

new BubbleDialog(this)
        .addContentView(LayoutInflater.from(this).inflate(R.layout.dialog_view3, null))
        .setClickedView(mButton4)
        .setPosition(mPosition)
        .setOffsetY(8)
        .show();

当想要输入框随软键盘上移时

exampel4

new BubbleDialog(this)
        .addContentView(LayoutInflater.from(this).inflate(R.layout.dialog_view, null))
        .setClickedView(mButton12)
        .setPosition(mPosition)
        .softShowUp()
        .show();

自定义 BubbleLayout

exampel5

BubbleLayout bl = new BubbleLayout(this);
bl.setBubbleColor(Color.YELLOW);
bl.setShadowColor(Color.RED);
bl.setLookLength(Util.dpToPx(this, 18));
bl.setLookWidth(Util.dpToPx(this, 24));
bl.setBubbleRadius(Util.dpToPx(this, 3));
new BubbleDialog(this)
        .addContentView(LayoutInflater.from(this).inflate(R.layout.dialog_view5, null))
        .setClickedView(mButton8)
        .setPosition(mPosition)
        .setBubbleLayout(bl)
        .show();

自定义 BubbleDialog,可交互的 BubbleDialog

exampel6

1、布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="160dp"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <Button
        android:id="@+id/button13"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Button1" />

    <Button
        android:id="@+id/button14"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Button2" />

    <Button
        android:id="@+id/button15"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Button3" />

</LinearLayout>

2、自定义 BubbleDialog

/**
 * 自定义可操作性dialog
 * Created by JiajiXu on 17-12-11.
 */

public class CustomOperateDialog extends BubbleDialog implements View.OnClickListener
{
    private ViewHolder mViewHolder;
    private OnClickCustomButtonListener mListener;

    public CustomOperateDialog(Context context)
    {
        super(context);
        setTransParentBackground();
        setPosition(Position.TOP);
        View rootView = LayoutInflater.from(context).inflate(R.layout.dialog_view4, null);
        mViewHolder = new ViewHolder(rootView);
        addContentView(rootView);
        mViewHolder.btn13.setOnClickListener(this);
        mViewHolder.btn14.setOnClickListener(this);
        mViewHolder.btn15.setOnClickListener(this);
    }

    @Override
    public void onClick(View v)
    {
        if (mListener != null)
        {
            mListener.onClick(((Button)v).getText().toString());
        }
    }

    private static class ViewHolder
    {
        Button btn13, btn14, btn15;
        public ViewHolder(View rootView)
        {
            btn13 = rootView.findViewById(R.id.button13);
            btn14 = rootView.findViewById(R.id.button14);
            btn15 = rootView.findViewById(R.id.button15);
        }
    }

    public void setClickListener(OnClickCustomButtonListener l)
    {
        this.mListener = l;
    }

    public interface OnClickCustomButtonListener
    {
        void onClick(String str);
    }
}

3、显示

CustomOperateDialog codDialog = new CustomOperateDialog(this)
        .setPosition(mPosition)
        .setClickedView(mButton10);
codDialog.setClickListener(new CustomOperateDialog.OnClickCustomButtonListener()
{
    @Override
    public void onClick(String str)
    {
        mButton10.setText("点击了:" + str);
    }
});
codDialog.show();

查看关于BappyDialog的使用代码

TestDialogActivity 代码

写法建议

根据@hm该朋友在文章中反馈的多次点击后位置不对的问题,是由于多次对BappyDialog进行了设置导致,所以建议下方写法。(当然如果对重复调用setClickedView()方法设置不同的被点击的控件来更新位置有需要,是需要写在外面的。)

if(mBubbleDialog == null)
{
    mBubbleDialog = new BubbleDialog(this)
        .addContentView(LayoutInflater.from(this).inflate(R.layout.dialog_view3, null))
        .setClickedView(mButton4)
        .setPosition(mPosition)
        .setOffsetY(8);
}
mBubbleDialog.show();

如何使用 HappyBubble-BubbleLayout?

在XML代码中设置属性值

属性参照表

属性 描述
lookAt left, top, right, bottom 箭头指向
lookLength dimension 箭头的长度
lookPosition dimension 箭头相对于x或y轴的位置
lookWidth dimension 箭头的宽度
bubbleColor color 气泡的颜色
bubbleRadius dimension 气泡四角的圆弧
bubblePadding dimension 气泡边缘到BubbleLayout边缘的距离
shadowRadius dimension 阴影的扩散大小
shadowX dimension 阴影在x轴方向的偏移
shadowY dimension 阴影在y轴方向的偏移
shadowColor color 阴影的颜色

xml 例子

    <com.xujiaji.happybubble.BubbleLayout
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/bubbleLayout"
        android:layout_width="match_parent"
        android:layout_height="200dp"
        android:layout_margin="16dp"
        app:lookAt="left"
        app:lookLength="16dp"
        app:lookPosition="20dp"
        app:lookWidth="16dp" />

在java代码中定义属性值

BubbleLayout 通过“set属性名”方法和invalidate方法来更新BubbleLayout。

mBubbleLayout.setLook(BubbleLayout.Look.LEFT);

查看更多

MainActivity 代码

GIF

demo 下载

GitHub release


License

   Copyright 2016 XuJiaji

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

happybubble's People

Contributors

xujiaji avatar y110231 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

happybubble's Issues

android.R.id.content 为null

view.getRootView().findViewById(android.R.id.content) 到这步,获取为null,百度,google没找到,请问这个是什么原因?

1.2.5下载不了,1.2.4可以,是不是没上传

气泡的Y轴位置有问题

D46E0C0A-EAC3-41BA-93DE-1A16EBDB76FF
不知道是什么原因造成的, 另一台机子位置就正常
代码:
mCurrentDialog = new BubbleDialog(getContext()) .setBubbleContentView(view) .setClickedView(ivEllipis) .setPosition(BubbleDialog.Position.TOP,BubbleDialog.Position.TOP); mCurrentDialog.show();
另外 : 建议开放手动设置Y轴位置的API,由调用者手动设置.

Recyclerview in dialog not getting populated.

`

public class CustomBubbleView extends BubbleDialog {

SymbolAdapter adapter;
StyleMakerAlphabetCallback callback;

public CustomBubbleView(final Context context) {
    super(context);
    setPosition(Position.BOTTOM);
    View rootView = LayoutInflater.from(context).inflate(R.layout.symboldialog, null);
   
    RecyclerView symbolRecycler = rootView.findViewById(R.id.symbolRecycler);
    symbolRecycler.setLayoutManager(new GridLayoutManager(context,5));
    
    adapter = new SymbolAdapter(context, symbols, new SymbolSelectCallback() {
        @Override
        public void OnSymbolSelected(String symbol) {
            callback.OnSymbolSelected(symbol);
        }
    });

    symbolRecycler.setAdapter(adapter);
    addContentView(rootView);
}


public void setClickListener(StyleMakerAlphabetCallback l)
{
    this.callback = l;
}`

it is my code for custom clickable dialog . Plz tell me what the problem is .

依赖

依赖拉取不了啊?1.2.6

关于 bubblePadding

bubblePadding设置为0 会导致阴影区域消失,我想要的是
image

bubblePadding 给值则会导致背景区域有边距,影响子布局绘制,
image

~我认为这块应该单独定义一个属性用来控制阴影的的尺寸

有些疑问,请教一下

你好,我使用它在listview里,是item一个imageview长按显示。但位置一是屏幕顶部,二就是屏幕底部,请问该如何设置能让它依附与item里的imageview或者该item上。还有个问题,每次bubbleDialog显示的时候会闪烁一下,这个也请问是需要设置哪里?谢谢你抽时间回答

在view的正下方显示不适配。。。

mBubbledialog = new BubbleDialog(context)
.addContentView(view)
// .setOffsetY(Util.dpToPx(context, -3))
.setBubbleLayout(bl).setClickedView(clickView)
.setPosition(BubbleDialog.Position.BOTTOM).setLayout(Util.dpToPx(context, 127),
Util.dpToPx(context, 110), Util.dpToPx(context, 1));

在三星S20 utral 手机上如果设置上setOffsetY为-5,才会在view的正下方显示。不然会离得很远。
在其他手机上不用设置setOffsetY为-5也会在view正下方显示。。。

几个问题

final View dialogMain = getLayoutInflater().inflate(R.layout.dialog_meeting_operation, null);
tvMute = dialogMain.findViewById(R.id.stv_mute);
tvTakenAway = dialogMain.findViewById(R.id.stv_taken_away);
tvShutUp = dialogMain.findViewById(R.id.stv_shut_up);

bubbleDialog = new BubbleDialog(this)
.setBubbleContentView(dialogMain)
.setTransParentBackground()
.setRelativeOffset(-16)
.setThroughEvent(true, true)
.autoPosition(Auto.UP_AND_DOWN);

mAdapter.setOnItemClickListener((holder, data) -> {
//item 点击事件
tvMute.setOnClickListener(this);
tvTakenAway.setOnClickListener(this);
tvShutUp.setOnClickListener(this);
bubbleDialog.setClickedView(holder.itemView);
bubbleDialog.show();
});

  1. 点击bubbleDialog外部不能消失,setThroughEvent(true, true)第二参数已经设置true了

2.setBubbleContentView的view和外部的有边距,setTransParentBackground()我理解的边框是透明的,怎么是白色的,怎么能设置边距,我想ContentView的view没有边距完全包裹。

3.在RecyclerView中item点击有的时候重复点击item,bubbleDialog会跑到上一个位置去了。

TextView自动换行了

默认状态下 箭头处于正中间
似乎由于箭头到右侧的距离不够 但箭头设置在最中间
所以为了保证他在中间 计算了左侧距离等于右侧距离 相加等于总距离
但是这个总距离不够我显示所有文字 于是TextView换行了
这个设计不是不行 但是不是能够更加智能化呢?
对于气泡提示来说 箭头是否是在正中间无所谓 只要位置出现的是指定的地方就可以了
再屏幕的距离能够满足的情况下 是否能够箭头自适应呢?

关于箭头位置问题

箭头位置能不能加上自动居中选项,只用固定值来控制箭头位置不够灵活

自动方向问题

是否可以设置方向优先级
比如 设置下方显示 当下方的空间不足时 自动调整为上方显示 左右也是如此
实例代码中 没有看到 gif 中设置 BubbleLayout 外边距的代码啊

碰到的一些问题

1、这种方式打开 dialog 会导致 dialog 展示在屏幕左上角,而不会显示在mIvMainToolLayer的左边。

image

image

2、IllegalStateException:The specified child already has a parent. You must call removeView() on the child's parent first.
当我在外层新建View,因为需要在其他界面对view做一些操作。我的想法是 Dialog一直是存活的,只是展示和隐藏

重复new 的时候会引发上述异常崩溃。
image

箭头位置在列表中设置无效

箭头位置在列表中设置无效;
BubbleLayout bl = new BubbleLayout(this);
bl.setLookPosition(Util.dpToPx(this, 10));
bl.setBubbleColor(Color.YELLOW);
bl.setShadowColor(Color.RED);
bl.setLookLength(Util.dpToPx(this, 18));
bl.setLookWidth(Util.dpToPx(this, 24));
bubbleDialog = new BubbleDialog(SetClickedViewTestActivity.this)
.addContentView(dialogMain)
.setTransParentBackground()
.setPosition(BubbleDialog.Position.TOP)
.setRelativeOffset(-16)
.setBubbleLayout(bl)
.setThroughEvent(true, false);
// .autoPosition(Auto.AROUND);

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.