BaseAdapter 상속받아서 커스텀 어댑터로 ListView 구현을 했습니다.
어댑터에서 이미지를 조건에 따라 setImageResource,setVisiblity 로 변경하였는데 의도한 결과랑 다르게 나오네요.
아래 코드에서 62,65 라인을 보시면 data의 조건에 따라 이미지리소스를 변경하거나 visibility를 변경하도록 하였으나
돌려보면 조건과는 무관하게 이미지가 바뀌어 버립니다.
문제가 되는 해당 라인에 break를 걸어 확인해본 결과 조건은 정상적인 경우에만 통과를 합니다.
즉 62라인의 isCurrent()이 false인때도 조건이 통과된 것처럼 이미지가 바뀌어있지만 setVisibility는 실행되지 않습니다.
(65라인에도 동일한 현상입니다.)
ListView 스크롤을 마구마구 하다보면 결국 모든 data가 조건을 통과한 것처럼 변경이 되버리네요.
그런데 재밌는건 TextView는 정상적으로 작동한다는점입니다 --;;
제가 예상하기로는 adapter의 row 캐싱 과정에서 생긴 문제이거나
여러군데에서 같은 ImageView를 참조하는 것 같은데 도저히 저로선 해결이 불가능 하네요..
참고로 ViewHolder 사용하지 않을때도 같은 현상입니다. 혹시나 사용하면 될줄 알았더니 안되네요..
개인적으로 해결이 가능할것 같다 싶으신분에게는 제가 직접 프로젝트 파일을 보내드릴 수 도 있습니다.. 꼭좀 해결해 주세요 ㅠㅠ
혹 해결이 불가능하더라도 리포트된 관련 버그가 있다면 알려주시면 감사하겠습니다.
레이아웃 소스도 함께 첨부합니다.
public class StationListArrayAdapter extends BaseAdapter
{
private class ViewHolder
{
TextView stNameView;
TextView stNumView;
ImageView line;
ImageView station;
ImageView current;
}
private int resId;
private LayoutInflater inflater = null;
private List<StationByRouteInfo> stationList = null;
public StationListArrayAdapter(Context context, int textViewResoureceId, List<StationByRouteInfo> items)
{
stationList = items;
resId = textViewResoureceId;
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
notifyDataSetChanged();
}
public void add(StationByRouteInfo data)
{
stationList.add(data);
notifyDataSetChanged();
}
public View getView(int position, View convertView, ViewGroup parent)
{
ViewHolder viewHolder;
if(convertView == null)
{
convertView = inflater.inflate(resId,parent,false);
viewHolder = new ViewHolder();
viewHolder.stNameView = (TextView) convertView.findViewById(R.id.stlist_name);
viewHolder.stNumView = (TextView) convertView.findViewById(R.id.stlist_num);
viewHolder.station = (ImageView) convertView.findViewById(R.id.stlist_staImg);
viewHolder.line = (ImageView) convertView.findViewById(R.id.stlist_line);
viewHolder.current = (ImageView) convertView.findViewById(R.id.stlist_currentImg);
convertView.setTag(viewHolder);
}
else
{
viewHolder = (ViewHolder) convertView.getTag();
}
StationByRouteInfo data = stationList.get(position);
if(data != null)
{
viewHolder.stNameView.setText(data.getStationNm());
viewHolder.stNumView.setText(data.getStationNo());
if(data.isFirstStation())
viewHolder.line.setImageResource(R.drawable.st_line_first);
if(data.isLastStation())
viewHolder.line.setImageResource(R.drawable.st_line_last);
if(data.isCurrent())
viewHolder.current.setVisibility(View.VISIBLE);
if(data.isTrnstn())
viewHolder.station.setImageResource(R.drawable.st_tran);
}
return convertView;
}
public int getCount()
{
return stationList.size();
}
public Object getItem(int position)
{
return stationList.get(position);
}
public long getItemId(int position)
{
return position;
}
} <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:background="#EEE"
android:gravity="center_vertical" >
<FrameLayout
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:id="@+id/frameLayout1"
android:layout_width="wrap_content"
android:layout_height="45dp" >
<ImageView
android:id="@+id/stlist_line"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleY="2"
android:src="@drawable/st_line" />
<ImageView
android:id="@+id/stlist_staImg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:contentDescription="standard station"
android:src="@drawable/st_standard" />
<ImageView
android:id="@+id/stlist_currentImg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:contentDescription="current"
android:src="@drawable/st_current_pin"
android:visibility="invisible" />
</FrameLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="@+id/stlist_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:maxWidth="270dp"
android:text="Station Nama"
android:textColor="#666"
android:textSize="20sp" />
<TextView
android:id="@+id/stlist_num"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="12345"
android:textColor="#BBB"
android:textSize="9sp" />
</LinearLayout>
</LinearLayout>
else에 대한 항목도 다 만들어 주셔야 되요~
getView가 멍청해서인지 View.VISIBLE만 해 놓으면 될줄 알았는데 그게 아니더라구요 ~_~
윗분들이 이미 잘 얘기해주셨지만, ListView 계열은 동일한 ListItem 을 보이는 부분만 설정해서 보여준다고 보시면 됩니다.
(정확한 표현, 동작방식은 아니지만, 이를테면,) 화면에 3개만 보이는 리스트에서 1번에서 보여주던 ListItem 이 스크롤로 올라가버리면 다시 보이지 않는 1번을 4번에서 재사용하는 방식입니다.
그래서, 위에서 if-else 식에서 else 를 처리해주지 않을경우, 이전 ListItem 의 속성을 따라 보여주지 말아야 하는 View 들이 VISIBLE 로 나올수 있습니다.




환승역, 출발역, 종착역, 현재역 처리가 있는데요...
그렇다면 중간에 지나가는 일반 역은 아예 데이터가 없나요?
만약 데이터가 있는 경우라면 이역시 명시적으로 처리하셔야 합니다.
visibility나 resource등등을 말이죠.
그리고 어떤 경우는 visibility만 바꾸고 어떤 경우는 이미지만 바꾸는데요.
이것도 else 조건을 다 만드셔야 할겁니다. 그래야 원하시는 대로 나올거에요.