1

I extends a ViewGroup which has listView in it. When I click the list item, I call the notifyDataChanged method, but it didn't work correctly, the getCount method is called but the getView method isn't called althought the getCount method return >0. Beside, I find that the listView is no longer clickable. I don't understand then. And if I reset the adapter by call setAdapter(adpater), the listView turn out to be empty, (but the getCount method is called, the getView method is not call, too.) Can anybody help me ?

code :

public class SelectDistrictView extends ViewGroup {

private ListView districtList = null;
private ListView sectionList = null;
private SelectDistrictAdapter districtAdapter = null;
private ArrayAdapter<String> sectionAdapter = null;

private List<String> districtStrList = null;
private int selectedDist = 2;

private ImageButton dismissBtn = null;
private PopupWindow pop = null;


public SelectDistrictView(Context context) {
    super(context);
    // TODO Auto-generated constructor stub
    ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);

    districtList = new ListView(context);
    sectionList = new ListView(context);
    districtList.setLayoutParams(params);
    sectionList.setLayoutParams(params);        

    districtStrList = new ArrayList<String>();
    districtStrList.add("区域1");
    districtStrList.add("区域2");
    districtStrList.add("区域3");
    districtAdapter = new SelectDistrictAdapter(context);
    districtList.setAdapter(districtAdapter);

    districtList.setBackgroundColor(Color.rgb(238, 238, 238));
    // districtList.setCacheColorHint(Color.argb(0, 0, 0, 0));
    // districtList.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
    // districtList.setSelector(R.drawable.bg_select_district);

    final Context _context= context;
    districtList.setOnItemClickListener(new OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
                long arg3) {
            // TODO Auto-generated method stub
            selectedDist = arg2;
            districtList.setSelection(arg2);
            //districtStrList.remove(0);
            //UpdateList task = new UpdateList();
            //SherlockActivity a = (SherlockActivity)_context;
            //a.runOnUiThread(task);
            districtAdapter.notifyDataSetChanged();
            //districtList.setAdapter(districtAdapter);
            Toast.makeText(_context, "" + arg2, Toast.LENGTH_SHORT).show();
        }
    });
    //districtList.setDivider(getResources().getDrawable(R.color.select_district_delive_color));
    //districtList.setSelector(R.drawable.select_district_list_selector);

    sectionAdapter = new ArrayAdapter<String>(context, android.R.layout.simple_list_item_1);
    sectionAdapter.add("商圈1");
    sectionAdapter.add("商圈2");
    sectionAdapter.add("商圈3");
    sectionAdapter.add("商圈4");
    sectionAdapter.add("商圈5");
    sectionAdapter.add("商圈3");
    sectionAdapter.add("商圈4");
    sectionAdapter.add("商圈5");
    sectionAdapter.add("商圈3");
    sectionAdapter.add("商圈4");
    sectionAdapter.add("商圈5");
    sectionList.setAdapter(sectionAdapter);
    sectionList.setBackgroundColor(Color.rgb(220, 220, 220));
    //sectionList.setSelector(Color.rgb(169, 207, 56));

    dismissBtn = new ImageButton(context);
    //dismissBtn.setBackgroundResource(R.drawable.select_district_dismiss);
    dismissBtn.setImageResource(R.drawable.select_district_dismiss);
    dismissBtn.setBackgroundDrawable(null);
    //dismissBtn.setGravity(Gravity.CENTER);
    dismissBtn.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            if (null != pop && pop.isShowing()) {
                pop.dismiss();
            }
        }
    });
}

public PopupWindow getPop() {
    return pop;
}

public void setPop(PopupWindow pop) {
    this.pop = pop;
}

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
    // TODO Auto-generated method stub
    boolean containDist = false, containSect = false, containDismiss = false;
    for(int i = 0; i < this.getChildCount(); i++) {
        View cView = this.getChildAt(i);
        if (cView == districtList) {
            containDist = true;
            continue;
        }

        if (cView == sectionList) {
            containSect = true;
            continue;
        }

        if (cView == dismissBtn) {
            containDismiss = true;
            continue;
        }

    }

    int lWidth = CommonFunction.dp2px(getContext(), 120);
    int fHeight = CommonFunction.dp2px(getContext(), 48);
    if (!containDist) {
        districtList.layout(0, 0, lWidth, b - t - fHeight);
        addViewInLayout(districtList, 0, null, true);
    }

    if (!containSect) {
        sectionList.layout(lWidth, 0, r - l, b - t - fHeight);
        addViewInLayout(sectionList, 0, null, true);
    }

    if (!containDismiss) {
        dismissBtn.layout(0, b - t - fHeight, r - l, b - t);
        addViewInLayout(dismissBtn, 0, null, true);
    }
    invalidate();
}

public static PopupWindow popSelector(Context context, View parent) {
    SelectDistrictView view = new SelectDistrictView(context);
    PopupWindow pop = new PopupWindow(view, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
    pop.setFocusable(true);
    pop.setOutsideTouchable(true);
    pop.setBackgroundDrawable(context.getResources().getDrawable(R.drawable.bg_select_district));
    //pop.showAtLocation(parent, Gravity.CENTER, 0, 0);
    view.setPop(pop);
    pop.showAsDropDown(parent, 0, 0);
    return pop;
}

private final class SelectDistrictAdapter extends BaseAdapter {

    private Context context = null;
    private LayoutInflater inflater = null;

    public SelectDistrictAdapter(Context context) {
        super();
        this.context = context;

        inflater = LayoutInflater.from(this.context);
    }

    @Override
    public int getCount() {
        // TODO Auto-generated method stub
        Log.v("reflesh", "all:" + districtStrList.size());
        return districtStrList.size();
    }

    @Override
    public Object getItem(int position) {
        // TODO Auto-generated method stub
        return districtStrList.get(position);
    }

    @Override
    public long getItemId(int position) {
        // TODO Auto-generated method stub
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        // TODO Auto-generated method stub
        Log.v("reflesh", "position:" + position);
        ViewHolder holder;
        if (null == convertView) {
            convertView = inflater.inflate(R.layout.select_district_list_item, null);

            holder = new ViewHolder();
            holder.tvName = (TextView)convertView.findViewById(R.id.select_district_list_item_name);
            holder.viewSelect = convertView.findViewById(R.id.select_district_list_item_selected_underline);
            holder.viewSelectTriangle = (ImageView)convertView.findViewById(R.id.select_district_list_item_selected_triangle);

            convertView.setTag(holder);
        } else {
            holder = (ViewHolder)convertView.getTag();
        }

        holder.tvName.setText(districtStrList.get(position));
        if(selectedDist == position) {
            //convertView.setBackgroundColor(Color.rgb(220, 220, 220));
            holder.viewSelect.setVisibility(View.VISIBLE);
            holder.viewSelectTriangle.setVisibility(View.VISIBLE);
        } else {
            //convertView.setBackgroundColor(Color.rgb(238, 238, 238));
            holder.viewSelect.setVisibility(View.GONE);
            holder.viewSelectTriangle.setVisibility(View.GONE);
        }

        return convertView;
    }
    private class ViewHolder {
        TextView tvName;
        View viewSelect;
        ImageView viewSelectTriangle;
    }
}

private class UpdateList implements Runnable {

    @Override
    public void run() {
        // TODO Auto-generated method stub
        districtAdapter.notifyDataSetChanged();
    }

}

}

after I saw the Question BaseAdapter notifyDatasetChanged() called but getView() is never called.

It turns out the problem with my getView() not being called is because it is not visible. My layout xml has the upper TextView with fill_parent for its height. Thus the entire view only has that single TextView visible.

Solution is thus: check the graphical view of the layout in question to make sure the ListView is visible.

And I think it may be the issue, but I don't how to solve it.

the item layout xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="48dp"
android:orientation="vertical" >
<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:minWidth="120dp" >

    <TextView
        android:id="@+id/select_district_list_item_name"
        android:textIsSelectable="false"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentRight="true"
        android:padding="12dp"
        android:textColor="#333333"
        android:textSize="16sp" />

    <View
        android:id="@+id/select_district_list_item_selected_underline"
        android:layout_width="match_parent"
        android:layout_height="2dp"
        android:layout_alignBottom="@id/select_district_list_item_name"
        android:background="#A9CF38" />

    <ImageView
        android:id="@+id/select_district_list_item_selected_triangle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_above="@id/select_district_list_item_selected_underline"
        android:layout_alignParentRight="true"
        android:contentDescription="@string/app_name"
        android:src="@drawable/select_district_selected_triangle" />
</RelativeLayout>
</LinearLayout>
Community
  • 1
  • 1
chops
  • 11
  • 4
  • i copy my code just now! Help me...... – chops Jun 23 '13 at 06:47
  • just curious, is any reason you extend ViewGroup? – pskink Jun 23 '13 at 06:52
  • I want to create a custom view because so many activity may use it. and the ViewGroup contain two ListView. As you see, I show this ViewGroup in a popupWindow. but the listView make me mad. – chops Jun 23 '13 at 07:00
  • just debug it, set a breakpoint in getCount, run, the step out from getCount and see what happens – pskink Jun 23 '13 at 07:32
  • it seems everything normal. And no exception is thrown either. – chops Jun 23 '13 at 07:59
  • and I find that if i scroll the ListView"districtList", the getView method will call. I can add item to the adapter, but the old item will never change. – chops Jun 23 '13 at 09:02
  • Is your "not working" always refers to calling notifyDataSetChanged after adding item to list view? Would you mind to tell us where and how are you adding items to districtStrList? Just FYI list item and notifyDataSetChanged has to be done by UI Thread itself – Chor Wai Chun Jun 23 '13 at 11:25
  • no matter add item or not(actually I just need to reflash the listView item without dataset changed), the notifyDataSetChanged doesn't work. and after I call the notifyDataSetChanged method, the listView become unclickable. I also try to call notifyDataSetChanged in the UI Thread, but it make nothing difference. – chops Jun 23 '13 at 13:15

1 Answers1

0

SOLVED: this problem is wierd. When I want to refresh the listView, I call the adapter.notifyDataSetChanged() method, then, call ListView.requestFocusFromTouch() method. This works for me.

Here is the code:

adapter.notifyDataSetChanged();
listView.requestFocusFromTouch();
backBtn.requestFocusFromTouch();// it is requred too. backBtn is other view in your layout

Can anybody explain it?

Piotr Chojnacki
  • 6,837
  • 5
  • 34
  • 65
chops
  • 11
  • 4