Android View 完美實現EditText 在軟鍵盤上邊的示例

此方法基於PopupWindow,適合需要回復內容時響應點擊事件,打開軟鍵盤,編輯框在軟鍵盤上部。
優點,編輯框使用CleanEdittext,監聽輸入狀態來更改回覆按鈕顏色,添加title等。

先展示效果

點擊評論打開軟鍵盤,編輯框在軟鍵盤上部,點擊其他區域消失收起軟鍵盤:

1.BaseSelectPopupWindow 的代碼。

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

public class BaseSelectPopupWindow extends PopupWindow {

 

private View popView;

 

private View view;

 

 

private OnHeadClickListener onHeadClickListener;

 

 

private TextView tv_head;

 

 

protected Context context;

 

 

private boolean isOpenKeyboard=false;;

 

 

private boolean isShowTitle=true;

 

private boolean isOkClose=true;

 

 

protected int maxTextSize = 24;

protected int minTextSize = 14;

public BaseSelectPopupWindow(Context context, int layoutId ) {

 

  this.context=context;

  LayoutInflater inflater = (LayoutInflater) context

      .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

  popView = inflater.inflate(R.layout.pop_view, null);

  tv_head=(TextView) popView.findViewById(R.id.tv_head);

 

  LinearLayout contentView = (LinearLayout) popView

      .findViewById(R.id.content);

  view=inflater.inflate(layoutId, null);

  contentView.addView(view,contentView.getLayoutParams());

  // btn_take_photo.setOnClickListener(itemsOnClick);

  // 設置SelectPicPopupWindow的View

  this.setContentView(popView);

  // 設置SelectPicPopupWindow彈出窗體的寬

  this.setWidth(LayoutParams.FILL_PARENT);

  // 設置SelectPicPopupWindow彈出窗體的高

 

  WindowManager wm = (WindowManager) context

      .getSystemService(Context.WINDOW_SERVICE);

//  this.setHeight(wm.getDefaultDisplay().getHeight() / 2);

  this.setHeight(LayoutParams.WRAP_CONTENT);

  // 設置SelectPicPopupWindow彈出窗體可點擊

  this.setFocusable(true);

  // 設置SelectPicPopupWindow彈出窗體動畫效果

  this.setAnimationStyle(R.style.AnimBottom);

  // 實例化一個ColorDrawable顏色爲半透明

  ColorDrawable dw = new ColorDrawable(0xb0000000);

  // 設置SelectPicPopupWindow彈出窗體的背景

  this.setBackgroundDrawable(dw);

  // mMenuView添加OnTouchListener監聽判斷獲取觸屏位置如果在選擇框外面則銷燬彈出框

 

  /*

   * popView.setOnTouchListener(new OnTouchListener() {

   *

   * public boolean onTouch(View v, MotionEvent event) {

   *

   * int height = popView.findViewById(R.id.pop_layout).getTop(); int

   * y=(int) event.getY(); if(event.getAction()==MotionEvent.ACTION_UP){

   * if(y<height){ dismiss(); } } return true; } });

   */

 

  (popView.findViewById(R.id.btn_back)).setOnClickListener(new OnClickListener() {

 

    @Override

    public void onClick(View v) {

       dismiss();

    }

  });

 

  (popView.findViewById(R.id.btn_right)).setOnClickListener(new OnClickListener() {

 

    @Override

    public void onClick(View v) {

      if(onHeadClickListener!=null){

        onHeadClickListener.okListener();

      }

      if(isOkClose){

        dismiss();

      }

 

    }

  });

 

  if(isOpenKeyboard){

    openKeyboard();

  }

 

 

 

}

public boolean isShowTitle() {

  return isShowTitle;

}

public void setShowTitle(boolean isShowTitle) {

  this.isShowTitle = isShowTitle;

  if(!isShowTitle){

    ((RelativeLayout)tv_head.getParent()).setVisibility(View.GONE);

  }

}

/**

 * 打開軟鍵盤

 */

private void openKeyboard() {

 

    Timer timer = new Timer();

    timer.schedule(new TimerTask() {

        @Override

        public void run() {

            InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);

            imm.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);

 

        }

    }, 1000);

}

public boolean isOpenKeyboard() {

  return isOpenKeyboard;

}

public void setOpenKeyboard(boolean isOpenKeyboard) {

  this.isOpenKeyboard = isOpenKeyboard;

}

 

public OnHeadClickListener getOnHeadClickListener() {

  return onHeadClickListener;

}

 

public void setOnHeadClickListener(OnHeadClickListener onHeadClickListener) {

  this.onHeadClickListener = onHeadClickListener;

}

 

public interface OnHeadClickListener{

  public void okListener();

}

 

 

 

public void setTitle(String value){

  if(tv_head!=null){

    tv_head.setText(value);

  }

}

public boolean isOkClose() {

  return isOkClose;

}

public void setOkClose(boolean isOkClose) {

  this.isOkClose = isOkClose;

}

public Context getContext() {

  return context;

}

對應的XML 佈局:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:background="@color/white_gray"

android:gravity="center_vertical" >

 

<RelativeLayout

  android:id="@+id/head"

  android:layout_width="match_parent"

  android:layout_height="44dp"

  android:layout_alignParentTop="true"

  android:background="@color/head_yellow" >

 

  <TextView

    android:id="@+id/btn_back"

    style="@style/nav_side_title_text"

    android:layout_width="wrap_content"

    android:layout_height="wrap_content"

    android:layout_alignParentLeft="true"

    android:layout_centerVertical="true"

    android:layout_marginLeft="15dp"

    android:text="@string/cancel"

    android:textColor="@color/black_light_color"

    android:textSize="@dimen/TitleTextSize" />

 

  <TextView

    android:id="@+id/tv_head"

    style="@style/nav_head_title_text"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:ellipsize="end"

    android:gravity="center"

    android:visibility="gone" />

 

  <TextView

    android:id="@+id/btn_right"

    style="@style/nav_side_title_text"

    android:layout_width="wrap_content"

    android:layout_height="wrap_content"

    android:layout_alignParentRight="true"

    android:layout_centerVertical="true"

    android:layout_marginRight="15dp"

    android:text="@string/sure"

    android:textColor="@color/black"

    android:textSize="@dimen/TitleTextSize" />

</RelativeLayout>

 

<LinearLayout

  android:id="@+id/content"

  android:layout_width="match_parent"

  android:layout_height="wrap_content"

  android:layout_below="@id/head"

  android:gravity="center"

  android:orientation="vertical" >

 </LinearLayout>

 

</RelativeLayout>

其中style:nav_side_title_text是定義文字大小的。

2.需要使用的時候

?

1

private BaseSelectPopupWindow popWiw;// 回覆的 編輯框

聲明之後使用的時候初始化並調用:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

private void popWiw( ) {

 

  popWiw = new BaseSelectPopupWindow(context, R.layout.edit_data);

  // popWiw.setOpenKeyboard(true);

  popWiw.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED);

  popWiw.setFocusable(true);

  popWiw.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);

  popWiw.setShowTitle(false);

  InputMethodManager im = (InputMethodManager) context

      .getSystemService(Context.INPUT_METHOD_SERVICE);

  im.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);

 

  final Button send = (Button) popWiw.getContentView().findViewById(

      R.id.btn_send);

  final EditText edt = (EditText) popWiw.getContentView().findViewById(

      R.id.edt_content);

 

  edt.setInputType(EditorInfo.TYPE_CLASS_TEXT);

  edt.setImeOptions(EditorInfo.IME_ACTION_SEND);

  edt.addTextChangedListener(new TextWatcher() {

 

    @Override

    public void onTextChanged(CharSequence s, int start, int before,

                 int count) {

      if (TextUtils.isEmpty(edt.getText())) {

        send.setEnabled(false);

      } else {

        send.setEnabled(true);

      }

    }

 

    @Override

    public void beforeTextChanged(CharSequence s, int start, int count,

                   int after) {

 

    }

 

    @Override

    public void afterTextChanged(Editable s) {

      // TODO Auto-generated method stub

 

    }

  });

  edt.setOnEditorActionListener(new TextView.OnEditorActionListener() {

 

    @Override

    public boolean onEditorAction(TextView v, int actionId,

                   KeyEvent event) {

      if (actionId == EditorInfo.IME_ACTION_SEND

          || (event != null && event.getKeyCode() == KeyEvent.KEYCODE_ENTER)) {

 

        if (!TextUtils.isEmpty(edt.getText().toString().trim())) {

      String content = edt.getText().toString().trim();

          // /提交內容  sumbit(content)

          popWiw.dismiss();

        }

        return true;

      }

      return false;

    }

  });

  send.setOnClickListener(new View.OnClickListener() {

 

    @Override

    public void onClick(View v) {

      if (!TextUtils.isEmpty(edt.getText().toString().trim())) {

 

        // /提交內容

        String content = edt.getText().toString().trim();

 

        popWiw.dismiss();

      }

    }

  });

 

  popWiw.setTitle("回覆" + nickname);

  popWiw.showAtLocation(refreshLayout, Gravity.BOTTOM

      | Gravity.CENTER_HORIZONTAL, 0, 0);

}

對應的edit_data xml佈局

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="match_parent"

android:layout_height="55dp" >

 

<RelativeLayout

  android:layout_width="match_parent"

  android:layout_height="44dp"

  android:background="@drawable/bg_search"

  android:gravity="clip_vertical"

  android:orientation="vertical"

  android:paddingLeft="12dp"

  android:paddingRight="12dp" >

 

  <com.myapp.view.ClearEditText

    android:id="@+id/edt_content"

    android:layout_width="match_parent"

    android:layout_height="55dp"

    android:layout_alignParentLeft="true"

    android:layout_centerVertical="true"

    android:layout_marginBottom="5dp"

    android:layout_marginRight="65dp"

    android:layout_marginTop="5dp"

    android:background="@drawable/edittext_back"

    android:focusable="true"

    android:hint="說點什麼..."

    android:paddingLeft="10dp"

    android:imeOptions="actionSend"

    android:paddingRight="10dp"

    android:textColor="@color/top_bg_shadow"

    android:textSize="@dimen/NormalTextSize" >

  </com.myapp.view.ClearEditText>

 

  <Button

    android:id="@+id/btn_send"

    android:layout_width="60dp"

    android:layout_height="34dp"

    android:layout_alignParentRight="true"

    android:layout_centerVertical="true"

    android:background="@drawable/btn_send_rounded"

    android:enabled="false"

    android:paddingLeft="12dp"

    android:paddingRight="12dp"

    android:text="@string/send"

    android:textColor="@color/white"

    android:textSize="@dimen/NormalTextSize" />

</RelativeLayout>

 

</LinearLayout>

對於ClearEditText,應該都不陌生,

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

public class ClearEditText extends EditText implements

  OnFocusChangeListener, TextWatcher {

/**

 * 刪除按鈕的引用

 */

private Drawable mClearDrawable;

 

public ClearEditText(Context context) {

  this(context, null);

}

 

public ClearEditText(Context context, AttributeSet attrs) {

  //這裏構造方法也很重要,不加這個很多屬性不能再XML裏面定義

  this(context, attrs, android.R.attr.editTextStyle);

}

 

public ClearEditText(Context context, AttributeSet attrs, int defStyle) {

  super(context, attrs, defStyle);

  init();

}

 

 

private void init() {

  //獲取EditText的DrawableRight,假如沒有設置我們就使用默認的圖片

  mClearDrawable = getCompoundDrawables()[2];

  if (mClearDrawable == null) {

    mClearDrawable = getResources()

        .getDrawable(R.drawable.icon_edit_del);

  }

  mClearDrawable.setBounds(0, 0, mClearDrawable.getIntrinsicWidth(), mClearDrawable.getIntrinsicHeight());

  setClearIconVisible(false);

  setOnFocusChangeListener(this);

  addTextChangedListener(this);

}

 

/**

 * 因爲我們不能直接給EditText設置點擊事件,所以我們用記住我們按下的位置來模擬點擊事件

 * 當我們按下的位置 在 EditText的寬度 - 圖標到控件右邊的間距 - 圖標的寬度 和

 * EditText的寬度 - 圖標到控件右邊的間距之間我們就算點擊了圖標,豎直方向沒有考慮

 */

@Override

public boolean onTouchEvent(MotionEvent event) {

  if (getCompoundDrawables()[2] != null) {

    if (event.getAction() == MotionEvent.ACTION_UP) {

      boolean touchable = event.getX() > (getWidth()

          - getPaddingRight() - mClearDrawable.getIntrinsicWidth())

          && (event.getX() < ((getWidth() - getPaddingRight())));

      if (touchable) {

        this.setText("");

      }

    }

  }

 

  return super.onTouchEvent(event);

}

 

/**

 * 當ClearEditText焦點發生變化的時候,判斷裏面字符串長度設置清除圖標的顯示與隱藏

 */

@Override

public void onFocusChange(View v, boolean hasFocus) {

  if (hasFocus) {

    setClearIconVisible(getText().length() > 0);

  } else {

    setClearIconVisible(false);

  }

}

 

 

/**

 * 設置清除圖標的顯示與隱藏,調用setCompoundDrawables爲EditText繪製上去

 * @param visible

 */

protected void setClearIconVisible(boolean visible) {

  Drawable right = visible ? mClearDrawable : null;

  setCompoundDrawables(getCompoundDrawables()[0],

      getCompoundDrawables()[1], right, getCompoundDrawables()[3]);

}

 

 

/**

 * 當輸入框裏面內容發生變化的時候回調的方法

 */

@Override

public void onTextChanged(CharSequence s, int start, int count,

    int after) {

  setClearIconVisible(s.length() > 0);

}

 

@Override

public void beforeTextChanged(CharSequence s, int start, int count,

    int after) {

 

}

 

@Override

public void afterTextChanged(Editable s) {

 

}

 

 

/**

 * 設置晃動動畫

 */

public void setShakeAnimation(){

  this.setAnimation(shakeAnimation(5));

}

 

 

/**

 * 晃動動畫

 * @param counts 1秒鐘晃動多少下

 * @return

 */

public static Animation shakeAnimation(int counts){

  Animation translateAnimation = new TranslateAnimation(0, 10, 0, 0);

  translateAnimation.setInterpolator(new CycleInterpolator(counts));

  translateAnimation.setDuration(1000);

  return translateAnimation;

}

}

一些icon 及圓角背景就不展示了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章