2012-12-26 3 views
1

Facebook 요청에서 JSONArray를 가져 오는 사용자 지정 어댑터와 함께 ListView를 사용하고 있습니다. 각 ListView 항목에는 게시물 유형에 따라 두 개의 TextView와 하나 또는 두 개의 ImageView가 있습니다. 각 목록 항목에는 "주석 상자"라고 부르는 LinearLayout도 있습니다.ListView의 동적 LinearLayout 항목

XML에서 목록 항목을 정의 할 때 설명 상자에는 제목 ("Comments and Likes")에 대한 TextView 만 포함됩니다. 사용자 정의 어댑터에서 주석 데이터를 구문 분석하고 TextViews를 프로그램 적으로 각 주석에 추가하여 빈 TextViews를 생성하거나 부 풀리지 않도록합니다.

일반적인 ListView 재활용 문제처럼 보이는 문제는 설명 상자가 목록을 스크롤 할 때 주석 상자의 내용을 유지하지 않는다는 것입니다. 나는 JSON 데이터를 살펴 보았고 배열의 모든 객체는 "comments"에 대한 필드가 같았 기 때문에 모든 데이터가로드되고 완벽하게 잘 채워지는 경우 데이터에서 null이 발생한다고 생각하지 않았습니다. . 나는 다른 모든 것이 작동하기 때문에 내가 잘못하고있는 것을 말할 수는 없지만 이것을한다. 다음은 내 어댑터의 getView() 메소드입니다.

public View getView(int position, View convertView, ViewGroup parent) { 

    final ViewHolder holder; 

    try { 
     jsonObject = getItem(position); 
     jsonFrom = jsonObject.getJSONObject("from"); 
     postType = jsonObject.getString("type"); 
     posterName = jsonFrom.getString("name"); 
     posterID = jsonFrom.getString("id"); 
     posterPhoto = "http://graph.facebook.com/" + posterID + "/picture?type=square"; 
     if (jsonObject.has("name")) { 
      posterMessage = jsonObject.getString("name"); 
     } 
     else if (jsonObject.has("story")){ 
      posterMessage = jsonObject.getString("story"); 
     } 
     else if (jsonObject.has("message")){ 
      posterMessage = jsonObject.getString("message"); 
     } 
     else{ 
      posterMessage = "No message."; 
     } 
     if(jsonObject.has("picture")){ 
      posterImageURL = jsonObject.getString("picture"); 
     } 
     commentsData = jsonObject.getJSONObject("comments"); 
     commentsCount = commentsData.getInt("count"); 


    } catch (JSONException e) { 
     e.printStackTrace(); 
    } 

    if (convertView == null) { 
     LayoutInflater inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     convertView = inflater.inflate(R.layout.post_holder,null); 
     holder = new ViewHolder(); 
     holder.posterName = (TextView) convertView.findViewById(R.id.posterName); 
     holder.posterMessage = (TextView) convertView.findViewById(R.id.posterMessage); 
     holder.posterProfilePhoto = (ImageView) convertView.findViewById(R.id.posterProfilePic); 
     holder.posterImage = (ImageView) convertView.findViewById(R.id.posterImage); 
     holder.commentsBox = (LinearLayout) convertView.findViewById(R.id.commentsBox); 
     if(postType.equals("photo")){ 
      holder.posterImage.setVisibility(View.VISIBLE); 
     } 
     if(commentsCount!=0 && commentsCount!=null){ 
      try { 
       commentsArray = commentsData.getJSONArray("data"); 
       for(int index = 0; index<commentsArray.length(); index++){ 
        comment = commentsArray.getJSONObject(index); 
        commenterName = comment.getJSONObject("from").getString("name"); 
        commenterId = comment.getJSONObject("from").getString("id"); 
        commentMessage = comment.getString("message"); 
        TextView commentMessageHolder = new TextView(activity); 
        commentMessageHolder.setText(Html.fromHtml("<b>"+commenterName+"</b>"+" "+commentMessage)); 
        holder.commentsBox.addView(commentMessageHolder, index+1); 
       } 
      } catch (JSONException e) { 
       e.printStackTrace(); 
      } 


     } 

     convertView.setTag(holder); 
    } 
    else { 
     holder = (ViewHolder) convertView.getTag(); 
     if(postType.equals("photo")){ 
      holder.posterImage.setVisibility(View.VISIBLE); 
     } 
     else{ 
      holder.posterImage.setVisibility(View.GONE); 
     } 
    } 

    if (jsonObject != null) { 
     holder.posterName.setText(posterName); 
     if (posterMessage != null) { 
      holder.posterMessage.setText(posterMessage); 
     } else { 
      holder.posterMessage.setText("No message for this post."); 
     } 

     imageLoader.displayImage(posterPhoto,holder.posterProfilePhoto); 

     if(postType.equals("photo")){ 
      if(posterImageURL != null){ 
       holder.posterImage.setTag(posterImageURL); 
       imageLoader.displayImage(posterImageURL, holder.posterImage); 
      } 
     } 
    } 

    return convertView; 

} 

답변

1

문제를 재활용 공통의 ListView 것 같아 제가하는 데 문제는, 이 목록을 스크롤 할 때 주석 상자의 내용을 유지하지 않습니다.

주요 문제는 주석을 구축한다는 것이다 TextViews사용자가이 ListView 당신이 (의견) 그 초기 설정 행을 전망하게 될 겁니다 스크롤 convertViewnull 인 경우, 만 그 원하지 않는 위치를 수정하지 마십시오. 주석 for을 에 null으로 표시하는 if 절 외부로 이동하십시오.

또한 json 구문 분석을 캐싱 할 수 있습니다. 덧글을 추가하지 말고 재생 된 행보기가 이미 자신의 설명 TextViews을 가질 수 있으므로 고려해야합니다.

+0

그게 전부입니다. 고마워요! 나는 안드로이드 프로그래밍에서 꽤 새로워 졌는데, 그래서 json 파싱을 캐시하기 위해 어떤 프로세스가 사용될 것인가? 감사. – Wenger

+0

행에 해당하는 json 구조의 모든 데이터 값을 보유 할 사용자 정의 객체의 목록 (데이터 크기 포함)을 가질 수 있습니다. 'getView' 메쏘드에서이리스트를 체크하여 당신이 그 행을 위해 저장되어있는 것이 있는지를 볼 것입니다. 그렇지 않으면 (처음에 그 위치에 도달했을 때) 현재 추출을 수행하고 목록에 데이터를 넣습니다. 다음에 해당 행에 도착하면 json 구조를 이미 파싱하고 목록에서 데이터를 검색하기 만하면됩니다. – Luksprog