위챗 모멘트를 모방하여 댓글을 클릭하면 자동으로 대응하는 위치로 이동합니다

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

좋은 웹페이지 즐겨찾기