2014-01-08 2 views
0

Я использую пользовательский listView и ArrayAdapter, который реализует sectionIndexer. Я использую Json для анализа данных с моего сервера. Я могу отображать данные в listView, но когда я нажимаю на свой список, он должен перейти к следующей подробной странице, но не работает на этом этапе.ANR, когда я нажимаю на элемент Item в спискеView

Вот код

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(); 
    } 


} 
} 

Из этого класса я создаю ListView в XML, активность

<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> 

Это XML для каждой строки в 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> 

Этот мой класс адаптера массива

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; 
} 

} 

И это мой класс активности

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); 
     } 



    }); 


} 
} 

Я не получаю никаких сведений об ошибках в LogCat или приложение не закрывается неожиданно вот почему я не могу решить эту проблему

Пожалуйста, помогите мне с этим , заранее спасибо.

+0

Вы сделали свой класс 'MasjidForListClass' доступным? – GrIsHu

+0

Что делает метод getlistOfMasjids(); '? – GrIsHu

ответ

0

ANR происходит потому, что вы выполняете длинную задачу в основной теме SelectMasjid. GetJsonList код должен быть перемещен в задаче async.

Вот документация AsyncTask

0

Для пользовательских ListView это хорошо для вас, чтобы использовать AsyncTask когда получить данные с сервера, как:

/** 
* Background Async Task to Load all product by making HTTP Request 
* */ 
class LoadAllItems extends AsyncTask<String, String, String> { 
    /** 
    * Before starting background thread Show Progress Dialog 
    * */ 
    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 
     pDialog = new ProgressDialog(YourActivityName.this); 
     pDialog.setMessage("Loading Items. Please wait..."); 
     pDialog.setIndeterminate(false); 
     pDialog.setCancelable(false); 
     pDialog.show(); 
    } 

    /** 
    * getting All products from url 
    * */ 
    protected String doInBackground(String... args) { 
     //your method that get data from server which getlistOfMasjids() 
     //Then save them in arrays or ArrayList, after that you can save them in listview 
        return null;      
    } 

    /** 
    * After completing background task Dismiss the progress dialog 
    * **/ 
    protected void onPostExecute(String file_url) { 
     // dismiss the dialog after getting all products 
     listview(); 
     pDialog.dismiss(); 
    } 
} 

Как отмечено в методе doInBackground вы можете использовать свой function getlistOfMasjids(), После этого вы можете сохранить данные в массивах или Arraylist, чтобы поместить их в listview.

для ListView в onPostExecute() метод это следующим образом:

public void listview(){ 
    adapter =new SelectMasjidAdapter(this, array1, array2,array3); 
    lv.setAdapter(adapter); 
} 

для списке следует ActionListener:

lv.setOnItemClickListener(new OnItemClickListener() { 
     public void onItemClick(AdapterView<?> parent, View view, 
       int position, long id) { 
      showInfo(position); // here you can put the call for another class or details item for specific position 

     } 
    }); 

Надежда действительно что будет полезно,

0

Android смирились очень хорошо документация по ANR и как сохранить отзывчивость приложения ... Я часто ссылаюсь на этот документ, когда я ударил ANR ..

http://developer.android.com/training/articles/perf-anr.html

Я создал правило для себя, как отпуск UI нить только для обработки пользовательского интерфейса, дб, гипергликемии, сеть должна быть сделана на не Ui нити ... Я использую нить и обработчик ... Все-таки когда-нибудь вам нужно сделать ожидание очереди ui, в этом случае у вас нет опции, но, насколько это возможно, избежать такой ситуации ...

Вы также можете использовать метод runOnUiThread для обновления ui из других потоков, отличных от ui. ..

Смежные вопросы