총 게시물 38,644건, 최근 7 건 안내 RSS 글쓰기
이전글  다음글  목록 글쓰기
[안드로이드]

RecyclerView itemView Click 시 문제

글쓴이 : 에찌 날짜 : 2017-04-14 (금) 11:32 조회 : 4029
글주소 : http://www.androidside.com/B49/166980
 
  SBS아카데미컴퓨터학원오현민
여름방학 미리 준비하자! LAYOUT 조기등록 최대 50% 할인
sbsit.co.kr
  모든데이터복구,긴급복구닥터
모든데이터복구업체 무료출장 저렴한견적 책임복구 최신복구장비 랜섬웨어, 복원,치료
18771718.tistory.com/
  부천스마트폰복구 3만원~
스마트폰복구 3만원,하드복구,외장하드복구,USB복구,블랙박스복구,마이크로SD복구
blog.naver.com/pysdora
신청하기


안드로이드, 자바 그리고 다양한 질문에 대해 성실히 답해드립니다. Q&A Jang

현재 RecyclerView를 이용해서 특정 리스트를 보여주고있습니다.
리스트는 잘 나오고 있는 상태이구요
클릭하면 해당 아이템 클릭도 잘됩니다.
클릭했을 경우 Gone 되어있던 RelativeLayout을 Visible시키고 한번더 누르면 Gone 시키도록 만들었죠.

그런데 문제가 생겼습니다.
해당 아이템 말고 아래에 있는 다른 아이템도 Visible 된다는 점입니다.
스크롤로 아래로 내려갔다가 위로 다시 올라오면 제가 클릭해서 VISIBLE 시켯던 아이템이 다시 gone 이 되어있구요
해당 visible, gone 은 클릭이벤트에서만 구동되도록 해놨습니다.
그리고 로그도 찍어봤는데 클릭했을 때 말고는 로그도 안찍혀있었구요..
설마해서 해당 레이아웃에 포함된 텍스트도 로그로 찍어서 확인해봤지만 제가 클릭했던 레이아웃의 텍스트만 정상적으로 출력이 되었습니다..

구글링을 계속 해보면서 해결방법들을 적용시켜봤지만 해결이 되지않더라구요..
관련 Adapter와 Fragment 를 올리겠습니다.

[ Adapter ]
public class MessageRecyclerAdapter extends RecyclerView.Adapter<MessageRecyclerAdapter.ViewHolder>{

private List<MessageItem> mMessageList;
private ItemClick itemClick;


public interface ItemClick {
public void onClick(View view, int position);
}

public void setItemClick(ItemClick itemClick) {
this.itemClick = itemClick;
}

public MessageRecyclerAdapter(List<MessageItem> list) {
this.mMessageList = list;
}

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.message_item, parent, false);
return new ViewHolder(view);
}

@Override
public void onBindViewHolder(final ViewHolder holder, int pos) {
Logger.d("onBindViewHolder : " + pos);
final int position = pos;
final MessageItem message = mMessageList.get(position);

holder.title.setText(message.getMessageTitle());
holder.date.setText(message.getMessageDate());

if (message.isReadMessage()) {
holder.read.setVisibility(View.GONE);
} else {
holder.read.setVisibility(View.VISIBLE);
}

holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Logger.d("holder onClick : " + message.getId());
if (itemClick != null) {
itemClick.onClick(v, position);
}
if (holder.contentLayout.getVisibility() == View.GONE) {
Logger.d("GONE");
if (!message.isReadMessage()) {
message.setReadMessage(true);
}
holder.contentLayout.setVisibility(View.VISIBLE);
holder.message.setText(message.getMessageContent());
holder.img.setImageBitmap(BitmapUtil.byteArrayToBitmap(message.getMessageImg()));

} else {
Logger.d("visible");
holder.contentLayout.setVisibility(View.GONE);
}
}
});
}

@Override
public int getItemCount() {
return mMessageList.size();
}

public MessageItem getItem(int position) {
return mMessageList.get(position);
}


public int getItemPositionToId(int id) {
for (int i = 0 ; i < mMessageList.size() ; i++) {
if (mMessageList.get(i).getId() == id) {
return i;
}
}
return -1;
}

public static class ViewHolder extends RecyclerView.ViewHolder {

@BindView(R.id.message_item_header)
RelativeLayout header;
@BindView(R.id.message_item_title)
TextView title;
@BindView(R.id.message_item_date)
TextView date;
@BindView(R.id.message_itme_read)
TextView read;
@BindView(R.id.message_item_message)
TextView message;
@BindView(R.id.message_item_img)
ImageView img;
@BindView(R.id.message_content_layout)
RelativeLayout contentLayout;
public View view;

public ViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
this.view = itemView;
}
}
}



[ Fragment ]
public class MessageMonsterFragment extends Fragment {

@BindView(R.id.message_monster_recycler)
RecyclerView mRecyclerView;

private RecyclerView.LayoutManager mLayoutManger;
private MessageRecyclerAdapter mMessageRecyclerAdapter;
private DBHelper dbHelper;
private Unbinder unbinder;

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

View view = inflater.inflate(R.layout.message_fragment_monster, container, false);
ButterKnife.setDebug(true);
unbinder = ButterKnife.bind(this, view);

dbHelper = new DBHelper(getActivity(), DBHelper.DB_NAME, null, DBHelper.DB_VERSION);
Logger.d("mRecyclerView : " + mRecyclerView);
mRecyclerView.setHasFixedSize(true);
mLayoutManger = new LinearLayoutManager(getActivity());
mRecyclerView.setLayoutManager(mLayoutManger);
mMessageRecyclerAdapter = new MessageRecyclerAdapter(getMessageList());
mRecyclerView.setAdapter(mMessageRecyclerAdapter);
mRecyclerView.setItemAnimator(new DefaultItemAnimator());

mMessageRecyclerAdapter.setItemClick(new MessageRecyclerAdapter.ItemClick() {
@Override
public void onClick(View view, int position) {
dbHelper.update(mMessageRecyclerAdapter.getItem(position).getId());
}
});

Bundle extra = getArguments();
if (extra != null) {
int selectId = getArguments().getInt("id", -1);
Logger.d("selecet ID : " + selectId);
if (selectId != -1) {
setFocusItem(selectId);
}
} else {
mRecyclerView.scrollToPosition(0);
}
return view;
}

private List<MessageItem> getMessageList() {
return dbHelper.getAllMessage();
}

public void setFocusItem(int id) {
final int position = mMessageRecyclerAdapter.getItemPositionToId(id);
if (id != -1) {
mRecyclerView.scrollToPosition(position);
mRecyclerView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
Logger.d("");
mRecyclerView.findViewHolderForAdapterPosition(position).itemView.performClick();
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
mRecyclerView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
} else {
mRecyclerView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
}
});

}
}

@Override
public void onDestroyView() {
super.onDestroyView();
unbinder.unbind();
}
}

그리고
만약 A부터 Z 까지 타이틀을 가진 아이템중 Z 아이템을 클릭 시 Z 아이템에 속해있는 레이아웃이 visible 되면서 B 와D 아이템의 레이아웃도 visible 되는데 그 레이아웃이 Z 아이템에 속해있는 레이아웃으로 VISIBLE이 됩니다.

이게 정말 크리티컬한 이슈인데 .. 왜 그런지 도저히 모르겠네요..ㅠㅠ




질문자가 자신의 포인트 15 점을 걸었습니다.
답변하시면 포인트 2을, 답변이 채택되면 포인트 12을 드립니다.

질문답변 게시판에서 궁금한 사항을 해결하셨다면, 애써 답변해주신 분께 잘 되었다고 따뜻한 댓글 한마디 남겨주세요.
그리고 답변해주신 분의 글을 '추천' 해주세요.
추천받으신 분에게 1포인트가, 추천하신 분에게도 1포인트가 적립됩니다. ^^

안사 이쁜이 2017-04-14 (금) 11:32
축하드립니다. ;)
에찌님은 안사 이쁜이에 당첨되어 4 포인트 지급되었습니다.
은빛파도 2017-04-14 (금) 11:54

if (!message.isReadMessage()) {

  message.setReadMessage(true);

}


이 부분을


if (!message.isReadMessage()) {

  message.setReadMessage(true);

} else {

  message.setReadMessage(false);

}


이렇게 바꿔주세요.

                
댓글주소 추천 0 반대 0
     
     
에찌 2017-04-14 (금) 11:59
[@은빛파도]
저거 리드메시지는 한번 읽으면 무조건 true로 해야해서여...^^;; 그래서 false부분을 안해놓은거에욤..
메시지 받았을 때 읽었으면 영원히 true가 되야해서욤..^^;
댓글주소 추천 0 반대 0
          
          
은빛파도 2017-04-14 (금) 12:04
[@에찌]

현재 저 부분으로 뷰를 visible / invisible 하기 때문에

Item에 디폴트값을 설정하시거나 값을 변경할때마다 notify를 해주셔야 합니다.
댓글주소 추천 0 반대 0
               
               
에찌 2017-04-14 (금) 13:38
[@은빛파도]
와 한참동안 고정관념에 사로잡혀있어서 이해를 못했는데 이제 이해가 되네요 ㅋㅋㅋ 
저는 리드메시지라고 하셔서 리드메시지는 아이템 visible, gone 이랑은 관계가 없는건데 왜 말씀하셧지했는데 채팅창에서 말씀하신 아이템.setRead부분을 계속 생각해보니 제 레이아웃 visible, gone 시키는 것을 아이템 모델쪽에서 셋팅해줘라라는 말씀으로 이해하니깐 해결이 된 것같네요 ㅎㅎ 우선 더 문제는 안보이긴 하지만 테스트좀 더 진행해봐야겠네요 ㅎㅎ 감사합니다.

그리고 홀더부분에 boolean 값을 셋팅해주니깐 스크롤링이나 클릭할때마다 뷰홀더가 계속 호출이 되면서 boolean 값은 계~~~~~~~~~~속 default로 적용되네여
왠만하면 홀더부분에서 boolean값 변경하는것은 안해줘야겠어요
이유는 잘 모르겠지만.. 

:) 감사합니다 ㅎㅎ
댓글주소 추천 0 반대 0
                    
                    
OSKiller 2017-04-14 (금) 14:32
[@에찌]
한참동안 하나만 보고 있으면 그렇게 되요
그래서 잘 해결 안될때는 잠깐 묵혀놨다가 나중에 보면 쉽게 해결되기도 합니다
혹은 옆사람을 불러서 같이 봐도 됩니다
옆에 사람이 한명 추가 된것만으로도 내가 코드를 바라보는 시각이 변하거든요
댓글주소 추천 0 반대 0
                         
                         
에찌 2017-04-14 (금) 14:46
[@OSKiller]
그렇지요..하지만 안드로이드 개발자는 저 뿐인걸요 ㅠㅠ 슬픔..우울..
그래두 안사멤버들이 옆에 있는거같아 힘이 나네요 감사해용 ㅎㅎㅎ
댓글주소 추천 0 반대 0
이전글  다음글  목록 글쓰기

 


Copyright ⓒ www.androidside.com. All rights reserved.
채팅 권한: 글쓰기 1개
2레벨 이상만 대화 가능
공개 채팅: 평일 !(9시 ~ 17시),토,일
안사2 변경사항 보러가기 챗방이 잘 안보이면 크롬에서 접속해주세요
챗방 숨기기 |  챗방 보이기