3

나는 RecyclerView으로 목록을 만듭니다. 모든 목록 항목은 사용자의 게시물입니다 (지금 하드 코딩 됨). 모든 게시물의 배경은 drawable 폴더의 layer-list XML 파일에서로드됩니다.Android RecyclerView는 첫 번째 항목의 배경색을 프로그래밍 방식으로 변경하지 않습니다.

모든 것이 텍스트 등으로 의도대로 작동하지만 배경색을 프로그래밍 방식으로 변경하려고합니다. 그것은 첫 번째 항목에 대해을 제외한 모든 항목의 배경색을 으로 변경합니다. 이유는 알 수 없습니다.

첫 번째 항목은 항상 XML 파일에 shape_background라는 item 내부의 shapesolid 색상에 의해 지정된 배경 색을 가져옵니다, 그래서 그것은 변경되지 않지만, 다음 항목은 색상 #ff22ff를 얻을.

이 어댑터의 구현 :

class PostListAdapter extends RecyclerView.Adapter<PostListAdapter.PostViewHolder>{ 

    private LayoutInflater inflater; 
    private List<PostRow> data = Collections.emptyList(); 

    PostListAdapter(Context context, List<PostRow> data) { 
     inflater = LayoutInflater.from(context); 
     this.data = data; 
    } 

    @Override 
    public void onBindViewHolder(PostViewHolder holder, int position) { 

     PostRow current = data.get(position); 
     holder.text.setText(current.text.toUpperCase()); 
     holder.time.setText(current.time.toUpperCase()); 
     holder.answers.setText(current.answers.toUpperCase()); 

     try { 
      // "#ff22ff" will be changed to current.color, unique color for every post 
      // That string is parsed from a JSON request, hence the try-catch. 
      int color = Color.parseColor("#ff22ff"); 
      holder.shape.setColor(color); 
     } catch (Exception e){ 
      e.printStackTrace(); 
     } 

    } 

    @Override 
    public PostViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
     View view = inflater.inflate(R.layout.post_row, parent, false); 
     return new PostViewHolder(view); 
    } 

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

    class PostViewHolder extends RecyclerView.ViewHolder { 

     TextView text; 
     TextView time; 
     TextView answers; 
     GradientDrawable shape; 

     PostViewHolder(View itemView) { 
      super(itemView); 
      text = (TextView) itemView.findViewById(R.id.text); 
      time = (TextView) itemView.findViewById(R.id.time); 
      answers = (TextView) itemView.findViewById(R.id.answers); 
      LayerDrawable layers = (LayerDrawable) ContextCompat.getDrawable(itemView.getContext(), R.drawable.bubble); 

      shape = (GradientDrawable) (layers.findDrawableByLayerId(R.id.shape_background)); 
     } 

    } 

} 

왜 첫 번째 항목의 배경이 변경되지 하지만 텍스트는?

미리 감사드립니다. 당신의 onBindViewHolder이, 당신이 (당신은 이미 XML 속성에 설정하는 것이, 당김 거품) 현재의 배경을 얻을 & 배경 색상을 변경할 필요가있는 경우 (홀더)보기를 얻을

LayerDrawable layerDrawable = (LayerDrawable) yourView.getBackground().getCurrent(); 
GradientDrawable gradientDrawable = (GradientDrawable) layerDrawable.findDrawableByLayerId(R.id. shape_background).getCurrent(); 
// set you color based on position 
gradientDrawable.setColor(Color.parseColor("#ff22ff")); 
+3

예외가 있습니까? 왜 잡으려고합니까? – natario

+0

의견이 명확하지 않은 것으로 알고 있습니다. 하드 코딩 된 문자열 "# ff22ff"는 나중에 current.color 문자열로 변경됩니다. 이 문자열은 JSON 응답에서 파싱됩니다. 따라서 무언가가 그 과정에서 엉망이 될 경우를 대비하여 try-catch로 둘러 쌉니다. 나는 코멘트를 고칠 것이다, 고마워. – Misklahr

답변

3

holder.shape.setColor(color);

하지만 holderView가 새로 고치지 않았습니다.

어쩌면 당신은 holderView

+0

감사합니다.이 방법으로 원하는 방식으로 내 문제를 해결했습니다. API를 15 이상 사용하므로 liubaoyua의 setBackground 응답을 내 경우에는 사용할 수 없지만 올바른 것입니다. – Misklahr

3

당신이 전화 한에

+0

이것은 맞습니다.하지만 setBackgroundDrawable은 더 이상 사용되지 않습니다. setBackground가 setBackgroundDrawable 메소드를 호출하더라도 API 레벨 16 이상에서는 setBackground를 사용해야합니다. – Misklahr

0

당신은 여기에 두 가지 문제가 새로 고침

holder.itemView.setBackgroundDrawable( ContextCompat.getDrawable(itemView.getContext(), R.drawable.bubble))

를 호출해야합니다.

먼저 드로어 블 자체는 변경하지만 배경은 볼 수 없습니다. 그것은 liubaoyua와 Vignesh Sundar의 답으로 해결됩니다.

둘째 - R.drawable.bubble을 정적으로 변경합니다. Android는 돌연변이 이후에도 캐시하고 재사용 할 수 있습니다. 다른 항목에 다른 색상을 사용하기 시작하면 다른 문제가 발생할 수 있습니다.

두 번째 문제를 해결하려면 먼저 android.graphics.drawable.Drawable#mutate 번으로 전화를 걸어야합니다.

기본적으로 같은 리소스에서로드 된 모든 드로어 블 인스턴스는 공통 상태를 공유합니다. 한 인스턴스의 상태를 수정하면 다른 모든 인스턴스에 동일한 수정 사항이 적용됩니다.

class PostViewHolder extends RecyclerView.ViewHolder { 

    TextView text; 
    TextView time; 
    TextView answers; 
    LayerDrawable layers; 
    GradientDrawable shape; 

    PostViewHolder(View itemView) { 
     super(itemView); 

     text = (TextView) itemView.findViewById(R.id.text); 
     time = (TextView) itemView.findViewById(R.id.time); 
     answers = (TextView) itemView.findViewById(R.id.answers); 

     layers = (LayerDrawable) ContextCompat 
       .getDrawable(itemView.getContext(), R.drawable.bubble) 
       .mutate(); 

     shape = (GradientDrawable) layers.findDrawableByLayerId(R.id.shape_background); 
     itemView.setBackground(layers); 
    } 

    void setColor(Color color) { 
     shape.setColor(color); 
     itemView.setBackgroundDrawable(layers); 
    } 
} 

수 있음은 작은 모양 레이어에서 .mutate()를 이동하여 간단하게 할 수 있습니다

은 그래서해야 다음과 같이 보입니다.