发射弹幕的Dialog

最近在做弹幕的功能,弹幕功能的实现是使用的DanmakuFlameMaster。这篇文章主要是分享发射弹幕的dialog的具体实现以及遇到的问题。

实现的效果如下:

这里写图片描述
这里写图片描述

现在就开始分享具体的代码实现:

问题一:点击某个按键发射弹幕,需要弹出EditText输入框,并且要不挤压布局。
最原始的思路是,让带有EditText控件的View浮在播放器view的上层。整体布局是一个FrameLayout。多次试验之后,发现每当EditText出现的时候,总是会把播放器的View向上挤压,视频播放的窗口会受到影响。效果如下:
这里写图片描述
后来经过大神指点,只要把这个View做成Dialog的样式就可以不会影响布局了。
dialog的View布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/ll_send"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="#F3F6F6"
    android:gravity="center_vertical"
    android:orientation="horizontal">


    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginBottom="7dp"
        android:layout_marginLeft="16dp"
        android:layout_marginRight="16dp"
        android:layout_marginTop="7dp"
        android:layout_weight="1"
        android:background="@drawable/edit_bg"
        android:gravity="center_vertical"
        android:orientation="horizontal">

        <EditText
            android:id="@+id/et_keywored"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:background="@null"
            android:hint="发送弹幕一起high!"
            android:imeOptions="flagNoExtractUi"
            android:maxLength="11"
            android:maxLines="1"
            android:paddingBottom="7dp"
            android:paddingLeft="14dp"
            android:paddingTop="7dp"
            android:textColor="#898989"
            android:textSize="16sp" />

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="7dp"
            android:src="@drawable/iv_dm_pen" />

        <TextView
            android:id="@+id/tv_textcount"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="7dp"
            android:layout_marginRight="14dp"
            android:text="10"
            android:textColor="#898989"
            android:textSize="20sp" />
    </LinearLayout>


    <Button
        android:id="@+id/btn_sub"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginRight="14dp"
        android:background="@drawable/chat_list_button_btn_send_n"
        android:text="发射"
        android:textColor="#FFFFFF"
        android:textSize="14sp" />
</LinearLayout>

EditText有这样一个属性 android:imeOptions=”flagNoExtractUi”
是控制使软键盘不全屏显示,只占用一部分屏幕。如果不设置,edittext会全屏显示。

具体的效果是参考的爱奇艺app。
问题二:
在dialog弹出的时候,输入法不能自动弹出来。
在网上查找了很多资料
1)显示输入法

inputManager.toggleSoftInput(InputMethodManager.SHOW_FORCED,0);

2)隐藏输入法

inputManager.toggleSoftInput(InputMethodManager.SHOW_FORCED,0);

没错显示和隐藏是一样的代码,成对使用就可以了。
但是遇到了问题,在dialog显示出来的时候,点击dialog外缘区域需要隐藏掉dialog和输入法。
监听的实现是这样的:

dialog.setCanceledOnTouchOutside(true);
        dialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
                                       @Override
                                       public void onCancel(final DialogInterface dialog) {
                                           inputManager.toggleSoftInput(InputMethodManager.SHOW_FORCED,0);
                                       }
                                   }
        );

3)遇到的问题
输入法不仅仅能在点击dialog外缘的时候隐藏,而它也自带一个隐藏的按键,如下图这里写图片描述
点击这个按键的时候,输入法就自己隐藏了。
动作:第一步 点击按钮自动弹出dialog 弹出输入法
第二步 点击输入法自带的下箭头的按键隐藏输入法
第三步 点击dialog 外缘,隐藏dialog。这个时候,你会发现一个问题,本来隐藏的键盘又自动弹出来了!
我的理解是:点击输入法自带的隐藏按键,更改了系统判断的键盘显示隐藏的标识符。由于上面的代码, 弹出和隐藏都是同一段代码,当键盘处于隐藏状态的时候,又调用了一次代码,键盘就自动显示出来了。
4)寻求解决方法 思路就是判断键盘的显示和隐藏的状态,如果键盘处于隐藏状态就不调用这个代码

inputManager.toggleSoftInput(InputMethodManager.SHOW_FORCED,0);

各种百度 google,发现大家监听软键盘是否隐藏的方法 基本是建立在一个认识上:
有一个view,如果键盘显示的话,应该会挤压布局,布局的高度会发生变化,通过监听这个高度是否改变来判断键盘是否显示。问题来了,我们的dialog形式的输入框,键盘弹出的时候,并不会挤压布局,他们提供的方法无效。
。。。。。。各种纠结。。。。。。。
5)最终的解决方法

et_keywored.setOnFocusChangeListener(new View.OnFocusChangeListener() {
                                                 @Override
                                                 public void onFocusChange(View v, boolean hasFocus) {
                                                     if (hasFocus) {
                                                         et_keywored.post(new Runnable() {
                                                             @Override
                                                             public void run() {
                                                                 InputMethodManager imm = (InputMethodManager) MainActivity.this.getSystemService(Context.INPUT_METHOD_SERVICE);
                                                                 imm.toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, 0);
                                                                 //自动弹出
                                                                 try {
                                                                     Thread.sleep(40);
                                                                 } catch (InterruptedException e) {

                                                                 }

                                                             }
                                                         });
                                                     }

                                                 }
                                             }
        );

用post() 和Thread.sleep()做了一个延时,让界面刷新不是那么快,键盘就能顺利的弹出。
隐藏键盘的方法:

 InputMethodManager imm = (InputMethodManager) MainActivity.this.getSystemService(Context.INPUT_METHOD_SERVICE);
                                               imm.toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, InputMethodManager.HIDE_NOT_ALWAYS);

测试小米3和普通的手机不一样,键盘隐藏的时候 也需要做一个延时:

et_keywored.post(new Runnable() {
                                                   @Override
                                                   public void run() {
                                                       InputMethodManager imm = (InputMethodManager) MainActivity.this.getSystemService(Context.INPUT_METHOD_SERVICE);
                                                       imm.toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, InputMethodManager.HIDE_NOT_ALWAYS);
                                                       try {
                                                           Thread.sleep(100);
                                                       } catch (Exception e) {

                                                       }

                                                   }
                                               });

问题三:dialog样式的调整问题:
最原始的效果如下:
这里写图片描述
可以看到输入框下边缘和输入法紧紧的挨着,显示效果并不好

//设置展示范围
WindowManager m = getWindowManager();
Display d = m.getDefaultDisplay();  //为获取屏幕宽、高
int width = d.getWidth();
dialog.getWindow().setLayout(width, 120); //设置生效
dialog.getWindow().setGravity(Gravity.BOTTOM);

因为设置了dialog 的高度为120px,所以不能显示padding的区域。
后来更改为

dialog.getWindow().setLayout((int) screenWith, WindowManager.LayoutParams.WRAP_CONTENT);     //设置生效
高度自适应。
查看源码
/**
 * Special value for the height or width requested by a View.
 * WRAP_CONTENT means that the view wants to be just large enough to fit
 * its own internal content, taking its own padding into account.
 */
public static final int WRAP_CONTENT = -2;

wrap_content 包含了自身view的padding。所以如果要显示边距的话,设置margin是不行的。

可以加我微信好友,进技术讨论群。

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值