admin管理员组

文章数量:1516870

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

实现的效果如下:

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

问题一:点击某个按键发射弹幕,需要弹出EditText输入框,并且要不挤压布局。
最原始的思路是,让带有EditText控件的View浮在播放器view的上层。整体布局是一个FrameLayout。多次试验之后,发现每当EditText出现的时候,总是会把播放器的View向上挤压,视频播放的窗口会受到影响。效果如下:

<?xml version="1.0" encoding="utf-8"?><LinearLayoutxmlns: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() {
                                       @OverridepublicvoidonCancel(final DialogInterface dialog) {
                                           inputManager.toggleSoftInput(InputMethodManager.SHOW_FORCED,0);
                                       }
                                   }
        );

3)遇到的问题
输入法不仅仅能在点击dialog外缘的时候隐藏,而它也自带一个隐藏的按键,如下图

inputManager.toggleSoftInput(InputMethodManager.SHOW_FORCED,0);

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

et_keywored.setOnFocusChangeListener(new View.OnFocusChangeListener() {
                                                 @OverridepublicvoidonFocusChange(View v, boolean hasFocus) {
                                                     if (hasFocus) {
                                                         et_keywored.post(new Runnable() {
                                                             @Overridepublicvoidrun() {
                                                                 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() {
                                                   @Overridepublicvoidrun() {
                                                       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.
 */publicstaticfinalint WRAP_CONTENT = -2;

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

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

本文标签: 的时候系统效果如下