위챗 모멘트를 모방하여 댓글을 클릭하면 자동으로 대응하는 위치로 이동합니다
12250 단어 안드로이드
1. 사고방식:
1. [평론] 컨트롤을 눌렀을 때 다이아로그가 뜨고 다이아로그는 ScrollView, 아래는 입력상자로 키보드가 뜨면 입력상자를 위로 올리는 효과를 실현한다.
2. RecyclerView가 미끄러져야 할 거리를 계산합니다.
3. 키보드의 표시와 숨김을 감청하고 숨길 때 dialog dismiss;
작성하는 동안 수정된 사항이 있습니다.
1. 리스트에 있는 [평론] 컨트롤을 클릭 이벤트의 리셋을 설정할 때 전체 itemView를 매개 변수로 리셋 방법에 전달한다. 이렇게 하면 이해하기 쉽고 [평론] 컨트롤에 margin을 설정한 경우도 직접 포함할 수 있다. 즉, 입력 상자 위쪽은 리스트와 item 아래쪽에 대응하는 것이다.
2. 다이어로그에서 scrollView를 클릭하면 다이어로그가 사라지는 이벤트를 추가합니다.
2. 실현 절차 및 코드 세션
1. 목록의 표시는 말할 필요도 없이 [평론]을 보고 이벤트 코드를 클릭한다.
//
itemView.findViewById(R.id.tv_comment).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// itemView ,position , :)
((MainActivity) mContext).showInputDialog(itemView, getAdapterPosition());
}
});
MainActivity에서 showInputDialog 메서드는 다음과 같습니다.
/**
* dialog
*
* @param itemView
* @param position
*/
public void showInputDialog(View itemView, int position) {
final int itemBottomY = getCoordinateY(itemView) + itemView.getHeight();//item y
dialog = new Dialog(this, android.R.style.Theme_Translucent_NoTitleBar);
View view = LayoutInflater.from(this).inflate(R.layout.dialog_input, null);
dialog.setContentView(view);
//scrollView , dialog dismiss, onClick
dialog.findViewById(R.id.scrollView).setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP)
dialog.dismiss();
return true;
}
});
dialog.show();
itemView.postDelayed(new Runnable() {
@Override
public void run() {
LinearLayout llCommentInput = dialog.findViewById(R.id.ll_comment_input);
int y = getCoordinateY(llCommentInput);
Log.i("display", "itemBottomY = " + itemBottomY + " input text y = " + y);
// RecyclerView, item
rv_content.smoothScrollBy(0, itemBottomY - y);
}
}, 300);
}
화면 컨트롤 왼쪽 상단 정점 y 좌표 가져오는 방법
/**
* y
*
* @param view
* @return
*/
private int getCoordinateY(View view) {
int[] coordinate = new int[2];
view.getLocationOnScreen(coordinate);
return coordinate[1];
}
2. 키보드의 표시와 숨김을 감청하여 관련 조작을 한다
두 가지 방법이 있다. (1)
getWindow().getDecorView().getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
handleWindowChange();
}
});
(2)
getWindow().getDecorView().addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
@Override
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
handleWindowChange();
}
});
해당되는 handleWindowChange() 방법:
/**
*
*/
private void handleWindowChange() {
Rect rect = new Rect();
getWindow().getDecorView().getWindowVisibleDisplayFrame(rect);//
Log.i("display ", "top = " + rect.top);
Log.i("display ", "bottom = " + rect.bottom);
int displayHeight = rect.bottom - rect.top;//app , - -
int totalHeight = getWindow().getDecorView().getHeight();
// 0.8 ,dismiss dialog
if ((float) displayHeight / totalHeight > 0.8)//0.8 ,
if (null != dialog && dialog.isShowing())
dialog.dismiss();
}
3. 마지막 item을 눌렀을 때 특수 처리: 원래 키보드가 뜨면 리커버리뷰를 자동으로 위로 올린다(물론 현재 activity가 설정한 window Soft Input Mode와 관련이 있다). 그러나 현재 키보드가 뜨면 입력한 레이아웃이 추가되어 마지막 item을 눌렀을 때 일부분이 가려지기 때문에 마지막 item을 눌렀을 때 특수 처리를 해야 한다.recyclerView에 레이아웃을 입력하는 등 높은 item을 추가합니다.방법은 다음과 같습니다.
입력 상자 팝업 처리:
/**
* dialog
*
* @param itemView
* @param position
*/
public void showInputDialog(View itemView, final int position) {
final int itemBottomY = getCoordinateY(itemView) + itemView.getHeight();//item y
dialog = new Dialog(this, android.R.style.Theme_Translucent_NoTitleBar);
View view = LayoutInflater.from(this).inflate(R.layout.dialog_input, null);
dialog.setContentView(view);
//scrollView , dialog dismiss, onClick
dialog.findViewById(R.id.scrollView).setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP)
dialog.dismiss();
return true;
}
});
dialog.show();
itemView.postDelayed(new Runnable() {
@Override
public void run() {
LinearLayout llCommentInput = dialog.findViewById(R.id.ll_comment_input);
int y = getCoordinateY(llCommentInput);
Log.i("display", "itemBottomY = " + itemBottomY + " input text y = " + y);
// item , item, RecyclerView
if (position == adapter.data.size() - 1) {
adapter.data.add(new BottomBean());
adapter.bottomHeight = llCommentInput.getHeight();
adapter.notifyDataSetChanged();
}
// RecyclerView, item
rv_content.smoothScrollBy(0, itemBottomY - y);
}
}, 300);
}
입력 상자를 숨길 때의 처리:
/**
*
*/
private void handleWindowChange() {
Rect rect = new Rect();
getWindow().getDecorView().getWindowVisibleDisplayFrame(rect);//
Log.i("display ", "top = " + rect.top);
Log.i("display ", "bottom = " + rect.bottom);
int displayHeight = rect.bottom - rect.top;//app , - -
int totalHeight = getWindow().getDecorView().getHeight();
// 0.8 ,dismiss dialog
if ((float) displayHeight / totalHeight > 0.8)//0.8 ,
if (null != dialog && dialog.isShowing()) {
dialog.dismiss();
// item , item
if (adapter.data.get(adapter.data.size() - 1) instanceof BottomBean) {
adapter.data.remove(adapter.data.size() - 1);
adapter.notifyDataSetChanged();
}
}
}
GitHub 주소:https://github.com/YINQIEIE/weixinCommnetDemo
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
VisualStudio에서 Ant를 사용하여 Native APK를 만듭니다.※2019/11/13 Gradle판의 기사도 올랐습니다. 자세한 내용은 을 참조하십시오. CEDEC2019의 " "이라는 세션에서 VisualStudio에서도 Gradle을 사용한 Native 앱을 만들 수 있다는 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.