androidlistviewandroid-arrayadaptersectionindexer

ANR when I click on list Item in a listView


I am using a custom listView and ArrayAdapter which implements sectionIndexer. I am using Json to parse data from my server. I can display the data on the listView but When I click on my listView it should go to next detailed page, but its not working at this point.

Here is the code

    public class CustomListView extends ListView {


private Context ctx;

private static int indWidth = 20;
private String[] sections;
private float scaledWidth;
private float sx;
private int indexSize;
private String section;
private boolean showLetter = true;
private Handler listHandler;

public CustomListView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    ctx = context;
}
public CustomListView(Context context, AttributeSet attrs) {
    super(context, attrs);
    ctx = context;

}

public CustomListView(Context context, String keyList) {
    super(context);
    ctx = context;

}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    scaledWidth = indWidth * getSizeInPixel(ctx);
    sx = this.getWidth() - this.getPaddingRight() - scaledWidth;

    Paint p = new Paint();
    p.setColor(Color.WHITE);
    p.setAlpha(100);

    canvas.drawRect(sx, this.getPaddingTop(), sx + scaledWidth,
            this.getHeight() - this.getPaddingBottom(), p);

    indexSize = (this.getHeight() - this.getPaddingTop() - getPaddingBottom())
            / sections.length;

    Paint textPaint = new Paint();
    textPaint.setColor(Color.DKGRAY);
    textPaint.setTextSize(scaledWidth / 2);

    for (int i = 0; i < sections.length; i++)
        canvas.drawText(sections[i].toUpperCase(),
                sx + textPaint.getTextSize() / 2, getPaddingTop()
                        + indexSize * (i + 1), textPaint);

    // We draw the letter in the middle
    if (showLetter & section != null && !section.equals("")) {

        Paint textPaint2 = new Paint();         
        textPaint2.setColor(Color.DKGRAY);
        textPaint2.setTextSize(2 * indWidth);

        canvas.drawText(section.toUpperCase(), getWidth() / 2,  getHeight() / 2, textPaint2);
    }
}
private static float getSizeInPixel(Context ctx) {
    return ctx.getResources().getDisplayMetrics().density;
}
@Override
public void setAdapter(ListAdapter adapter) {
    super.setAdapter(adapter);
    if (adapter instanceof SectionIndexer)
        sections = (String[]) ((SectionIndexer) adapter).getSections();
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    float x = event.getX();

    switch (event.getAction()) {
    case MotionEvent.ACTION_DOWN: {
        if (x < sx)
            return super.onTouchEvent(event);
        else {
            // We touched the index bar
            float y = event.getY() - this.getPaddingTop() - getPaddingBottom();
            int currentPosition = (int) Math.floor(y / indexSize);

            section = sections[currentPosition];
            this.setSelection(((SectionIndexer) getAdapter())
                    .getPositionForSection(currentPosition));
        }
        break;
    }
    case MotionEvent.ACTION_MOVE: {
        if (x < sx)
            return super.onTouchEvent(event);
        else {
            float y = event.getY();
            int currentPosition = (int) Math.floor(y / indexSize);
            section = sections[currentPosition];
            this.setSelection(((SectionIndexer) getAdapter())
                    .getPositionForSection(currentPosition));

        }
        break;

    }
    case MotionEvent.ACTION_UP: {

        listHandler = new ListHandler();
        listHandler.sendEmptyMessageDelayed(0, 30 * 1000);

        break;
    }
  }
    return true;
}


private class ListHandler extends Handler {

    @Override
    public void handleMessage(Message msg) {            
        super.handleMessage(msg);           
        showLetter = false;
        //CustomListView.this.invalidate();
    }


}
}

From this class I am creating listview in xml,activity

 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:paddingBottom="@dimen/activity_vertical_margin"
  android:paddingLeft="@dimen/activity_horizontal_margin"
  android:paddingRight="@dimen/activity_horizontal_margin"
  android:paddingTop="@dimen/activity_vertical_margin"
  tools:context=".MainActivity" >

  <SearchView
    android:id="@+id/searchView1"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_alignParentTop="true" >
  </SearchView>

  <com.deiontech.masjidtimetableapp.CustomListView 
    android:id="@+id/listViewformasjid"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerHorizontal="true"
    android:layout_centerVertical="true" 
    android:layout_below="@+id/searchView1"
    android:clickable="true"/>
  </RelativeLayout>

This is a xml for each row in listView

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="3dp"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >

<TextView
    android:id="@+id/textView_name"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentLeft="true"
    android:layout_alignParentTop="true"
    android:focusable="false"
    android:text="t1" />

<TextView
    android:id="@+id/textView_country"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_alignLeft="@+id/textView_name"
    android:layout_below="@+id/textView_name"
    android:layout_marginTop="19dp"
    android:focusable="false"
    android:text="t2" />

<TextView
    android:id="@+id/textView_localarea"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignLeft="@+id/textView_country"
    android:layout_below="@+id/textView_country"
    android:layout_marginTop="15dp"
    android:focusable="false"
    android:text="t3" />

</RelativeLayout>

This is my array adapter class

public class SelectMasjidAdapter extends ArrayAdapter< MasjidForListClass> implements
 SectionIndexer{

private List< MasjidForListClass> itemList;
private Context context;
private static String sections = "abcdefghilmnopqrstuvz";

ArrayList< MasjidForListClass> data;

public SelectMasjidAdapter(List< MasjidForListClass> itemList, Context ctx) {
    super(ctx,R.layout.select_masjid_list_row, itemList);
    this.itemList = itemList;
    this.context = ctx;     
}

@Override
public int getCount() {
    // TODO Auto-generated method stub
    return itemList.size();
}

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

@Override
public long getItemId(int arg0) {
    return itemList.get(arg0).hashCode();

}

@Override
public View getView(int arg0, View arg1, ViewGroup arg2) {
    LayoutInflater inflater = (LayoutInflater)    
        context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View vi=arg1;
    if(arg1==null)

        vi = inflater.inflate(R.layout.select_masjid_list_row, null);

    TextView masjid_name_text = (TextView)vi.findViewById(R.id.textView_name); 
    TextView masjid_country_text = (TextView)vi.findViewById(R.id.textView_country); 
    TextView masjid_localarea_text = 
   (TextView)vi.findViewById(R.id.textView_localarea); 



    MasjidForListClass m = itemList.get(arg0);

    masjid_name_text.setText(m.getMasjidname());
    masjid_country_text.setText(m.getMasjidcountry());
    masjid_localarea_text.setText(m.getMasjidlocalarea());

    return vi;
}
@Override
public int getPositionForSection(int sectionIndex) {
    Log.d("ListView", "Get position for section");
    for (int i=0; i < this.getCount(); i++) {
        String item = this.getItem(i).getMasjidname().toLowerCase();
        if (item.charAt(0) == sections.charAt(sectionIndex))
            return i;
    }
    return 0;
}
@Override
public int getSectionForPosition(int position) {
    Log.d("ListView", "Get section");
    return 0;
}
@Override
public Object[] getSections() {
    Log.d("ListView", "Get sections");
    String[] sectionsArr = new String[sections.length()];
    for (int i=0; i < sections.length(); i++)
        sectionsArr[i] = "" + sections.charAt(i);

    return sectionsArr;
}

}

And this is my activity class

public class SelectMasjid extends Activity{

SelectMasjidAdapter adapter;
ListView masjidListView;
 List <MasjidForListClass> masjidnames;

@Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.select_masjid_activity);
    GetJsonList l = new GetJsonList();
    masjidnames = l.getlistOfMasjids();


    Collections.sort(masjidnames, new Comparator<MasjidForListClass>() {
        public int compare(MasjidForListClass result1, MasjidForListClass 
 result2) {
            return result1.getMasjidname().compareTo(result2.getMasjidname());
        }
    });

    masjidListView = (ListView)findViewById(R.id.listViewformasjid);
    adapter = new SelectMasjidAdapter(masjidnames,this);
    masjidListView.setAdapter(adapter);


    masjidListView.setOnItemClickListener(new OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
                long arg3) {

            Intent i = new Intent(SelectMasjid.this, 
 MasjidDetailedActivity.class);
            i.putParcelableArrayListExtra("selected", (ArrayList<? 
extends Parcelable>) masjidnames);
            i.putExtra("index", arg2);
            startActivity(i);
        }



    });


}
}

I am not getting any error details in logcat or the application is not closing unexpectedly thats why I cant resolve this problem

Please help me with this, thanks in advance.


Solution

  • ANR is happening because you are performing long task in the main thread of SelectMasjid activity. GetJsonList code should be moved in an async task.

    Here is the documentation of AsyncTask