点击/触摸无法在ListView上运行

时间:2012-03-20 11:21:17

标签: android android-listview

我使用过ListView并将自定义的ArrayAdapter绑定到它 将setOnItemClickListener(...)绑定到它。

还有2个按钮,'next'和'previous'。点击每个按钮,我调用一个webservice,根据收到的响应,我更新了适配器(并期望ListView得到更新。)

我的问题是,经过几次下次和之前的点击后,Touch无法在ListView上运行。

花了很多时间搞清楚,请帮帮我。 我的一个发现是:通常观察到GC后出现问题。

布局代码:

  <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
   android:layout_height="fill_parent"
   android:background="@drawable/background"
   android:orientation="vertical" >
   <LinearLayout
       android:id="@+id/layout1"
       style="@style/TitleBar"
       android:background="@drawable/top_bg" >
       <TextView
           android:id="@+id/search_result_titleTxt"
           style="@style/TitleBarText"
           android:paddingLeft="8dip"
           android:text="@string/title_restaurants" />
       <ImageView
           android:id="@+id/sep"
           android:layout_width="1px"
           android:layout_height="fill_parent"
           android:layout_marginRight="7dip"
           android:background="@drawable/seprator_img" />
       <ImageView
           android:id="@+id/img1"
           style="@style/TitleBarLogo"
           android:background="@null"
           android:onClick="onMapClick"
           android:src="@drawable/map" />
       <ImageView
           android:id="@+id/filterSep"
           android:layout_width="1px"
           android:layout_height="fill_parent"
           android:layout_marginRight="7dip"
           android:background="@drawable/seprator_img" />
       <ImageView
           android:id="@+id/filter"
           style="@style/TitleBarLogo"
           android:background="@null"
           android:onClick="onSearchClick"
           android:src="@drawable/filter" />
   </LinearLayout>
   <LinearLayout
       android:layout_width="fill_parent"
       android:layout_height="wrap_content"
       android:layout_weight="1"
       android:background="@drawable/background"
       android:padding="6dip" >
       <LinearLayout
           android:id="@+id/search_contentView"
           android:layout_width="fill_parent"
           android:layout_height="wrap_content"
           android:orientation="vertical" >
           <TextView
               android:id="@+id/search_result_countTxt"
               android:layout_width="fill_parent"
               android:layout_height="wrap_content"
               android:focusable="false"
               android:text="@string/total_restaurants"
               android:textColor="#ffffff"
               android:visibility="gone" />
           <ListView
               android:id="@+id/search_result_list"
               android:layout_width="fill_parent"
               android:layout_height="wrap_content"
               android:layout_weight="1"
               android:background="@layout/customshape_table"
               android:cacheColorHint="#00000000"
               android:divider="#BAC698"
               android:dividerHeight="2px"
               android:paddingLeft="4dip"
               android:paddingRight="4dip"
               android:scrollbars="none" />
           <LinearLayout
               android:id="@+id/layout1"
               android:layout_width="fill_parent"
               android:layout_height="wrap_content"
               android:layout_alignParentBottom="true"
               android:layout_marginTop="5dp" >
               <ImageView
                   android:id="@+id/search_result_prevBtn"
                   android:layout_width="wrap_content"
                   android:layout_height="wrap_content"
                   android:layout_gravity="left"
                   android:layout_weight="1"
                   android:background="@null"
                   android:onClick="onPrevBtnClick"
                   android:src="@drawable/previous_btn"
                   android:visibility="gone" />
               <ImageView
                   android:id="@+id/search_result_nextBtn"
                   android:layout_width="wrap_content"
                   android:layout_height="wrap_content"
                   android:layout_gravity="right"
                   android:layout_weight="1"
                   android:background="@null"
                   android:gravity="right"
                   android:onClick="onNextBtnClick"
                   android:src="@drawable/next_btn"
                   android:visibility="gone" />
           </LinearLayout>
       </LinearLayout>
   </LinearLayout>
   <HorizontalScrollView
       android:id="@+id/bottomBar"
       android:layout_width="fill_parent"
       android:layout_height="55dip"
       android:layout_alignParentBottom="true"
       android:background="@drawable/bottom_bar"
       android:scrollbarSize="2dip"
       android:scrollbarThumbHorizontal="@drawable/scrollbar_horizontal_thumb"
       android:scrollbarTrackHorizontal="@drawable/scrollbar_horizontal_track" >
       <LinearLayout
        ...
       </LinearLayout>
   </HorizontalScrollView>

适配器代码:

public class LazyListAdapter extends ArrayAdapter<Resturant> {

private ArrayList<Resturant> resturants;
public ImageLoader imageLoader;

Context context;
int layoutResourceId;

public LazyListAdapter(Context context, int layoutResourceId,
        ArrayList<Resturant> resturants) {
    super(context, layoutResourceId, resturants);
    this.layoutResourceId = layoutResourceId;
    this.context = context;
    this.resturants = resturants;
    imageLoader = new ImageLoader(context);
    setNotifyOnChange(true);
}

public static class ViewHolder {
    public TextView restaurantName;
    public TextView address;
    public TextView completeAddress;
    public TextView cuisines;
    public ImageView image;
    ImageView offerImg;
    ImageView freqImg;
    TextView dinnerCountImg;
    ImageView friDashImg;
    ImageView friEveDashImg;
    ImageView satDashImg;
    ImageView satEveDashImg;
    ImageView sunDashImg;
    ImageView sunEveDashImg;
    ImageView callImg;
    TextView metricTxt;
    TextView distanceTxt;
    View overlay;

}

public View getView(int position, View convertView, ViewGroup parent) {
    View vi = convertView;
    ViewHolder holder;
    if (convertView == null) {
        System.out.println("pos:::::::::: " + position);
        LayoutInflater inflater = ((Activity)context).getLayoutInflater();
                    vi = inflater.inflate(layoutResourceId, parent, false);
        holder = new ViewHolder();
        holder.restaurantName = (TextView) vi
                .findViewById(R.id.search_item_restTitleTxt);
        holder.address = (TextView) vi
                .findViewById(R.id.search_item_addTxt);
        holder.completeAddress = (TextView) vi
                .findViewById(R.id.search_item_complete_addTxt);
        holder.cuisines = (TextView) vi
                .findViewById(R.id.search_item_cuisineTxt);
        holder.image = (ImageView) vi.findViewById(R.id.search_item_image);
        holder.offerImg = (ImageView) vi
                .findViewById(R.id.search_item_specialOfferImg);
        holder.freqImg = (ImageView) vi
                .findViewById(R.id.search_item_frequencyImg);
        holder.dinnerCountImg = (TextView) vi
                .findViewById(R.id.search_item_dinnerCountTxt);
        holder.friDashImg = (ImageView) vi
                .findViewById(R.id.search_item_friDashImg);
        holder.friEveDashImg = (ImageView) vi
                .findViewById(R.id.search_item_friDashEveImg);
        holder.satDashImg = (ImageView) vi
                .findViewById(R.id.search_item_satDashImg);
        holder.satEveDashImg = (ImageView) vi
                .findViewById(R.id.search_item_satDashEveImg);
        holder.sunDashImg = (ImageView) vi
                .findViewById(R.id.search_item_sunDashImg);
        holder.sunEveDashImg = (ImageView) vi
                .findViewById(R.id.search_item_sunDashEveImg);
        holder.callImg = (ImageView) vi
                .findViewById(R.id.search_item_callImg);
        holder.metricTxt = (TextView) vi
                .findViewById(R.id.search_item_metricTxt);
        holder.distanceTxt = (TextView) vi
                .findViewById(R.id.search_item_distanceTxt);
        holder.overlay = vi.findViewById(R.id.overlay);

        vi.setTag(holder);
    } else
        holder = (ViewHolder) vi.getTag();

    holder.restaurantName.setText(getCustomText(resturants.get(position)
            .getName()));
    holder.address.setText(getCustomText(resturants.get(position)
            .getAddress()));
    holder.completeAddress.setText(getCustomText(resturants.get(position)
            .getMergedAddress()));
    holder.cuisines.setText(Html.fromHtml(getCustomText("<b>Cuisine: </b>"
            + resturants.get(position).getCuisines())));
    imageLoader.DisplayImage(resturants.get(position).getImagePath(),
            holder.image);
    setAvalIcons(position, holder);
    getDistance(position, holder);

    if (resturants.get(position).getSpecialOffer() != null
            && !resturants.get(position).getSpecialOffer()
                    .equals(StringConstants.EMPTY_STRING)) {
        holder.overlay
                .setBackgroundResource(R.drawable.specialoffers_strip);
        holder.overlay.invalidate();
    }
    return vi;
}

private void getDistance(int position, ViewHolder holder) {
    Setting setting = ((AppDelegate) ((Activity)context).getApplication())
            .getSetting();
    Resturant resturant = resturants.get(position);
    if (setting.getDistance() == 0) {
        holder.metricTxt.setText("miles");
        holder.distanceTxt.setText(resturant.getLocation());
    } else {
        holder.metricTxt.setText("kms");
        holder.distanceTxt.setText(resturant.getLocationInKm());
    }
}

public String getCustomText(String text) {
    if (text.length() > 30) {
        text = text.substring(0, 26);
        text = text + "...";
    }
    return text.toString();
}

public void reSet(ArrayList<Resturant> resturantsCache) {
    System.out.println("reSet(Resturant[] resturants) resturant :: "
            + resturantsCache.size());
    this.resturants = resturants;
    notifyDataSetChanged();
}

private void setAvalIcons(int position, ViewHolder holder) {
    Resturant resturant = resturants.get(position);
    System.out.println("Special offer image Visibility :: "
            + resturant.getSpecialIconsVisibility(0));
    System.out.println("Special offer image  :: " + holder.offerImg);
    holder.offerImg.setVisibility(resturant.getSpecialIconsVisibility(0));
    imageLoader.DisplayImage(resturant.getOfferImage(), holder.offerImg);
    holder.freqImg.setVisibility(resturant.getSpecialIconsVisibility(1));
    if (resturant.getSpecialIconsVisibility(1) == View.VISIBLE) {
        holder.freqImg.setImageResource(resturant
                .getFrequencyImageDrawableId());
    }
    holder.dinnerCountImg.setVisibility(resturant
            .getSpecialIconsVisibility(2));
    holder.dinnerCountImg.setText(resturant.getDinersPerCard() + "D");
    holder.friDashImg.setVisibility(resturant.getSpecialIconsVisibility(3));
    holder.friEveDashImg.setVisibility(resturant
            .getSpecialIconsVisibility(4));
    holder.satDashImg.setVisibility(resturant.getSpecialIconsVisibility(5));
    holder.satEveDashImg.setVisibility(resturant
            .getSpecialIconsVisibility(6));
    holder.sunDashImg.setVisibility(resturant.getSpecialIconsVisibility(7));
    holder.sunEveDashImg.setVisibility(resturant
            .getSpecialIconsVisibility(8));
    holder.callImg.setVisibility(resturant.getSpecialIconsVisibility(9));
}

public void clearCache() {
    imageLoader.clearCache();
}

@Override
public void clear() {
    clearCache();
    super.clear();
}
}

列表类:

公共抽象类SearchResultAbstractActivity扩展了Activity实现         OnItemClickListener {

protected LazyListAdapter adapter;
protected SearchResults searchResults;
protected SearchCriteria searchCriteria;
protected boolean isGuest = false;
protected ProgressDialog dialog;
protected String responseString;
protected boolean isNew = false;
protected boolean isFilter = false;
private View contentView;
protected static final String RETRIVE_RESTAURANTS = "RetriveRestaurants";
protected static final String DELETE_FAVOURITES = "DeleteFavourites";
protected static final String LOADING_MSG = "please wait\n\nloading restaurants...";
Handler mHandler = new Handler() {

    public void handleMessage(android.os.Message msg) {
        if (!isFinishing()) {
            Bundle b = msg.getData();
            String action = b.getString(StringConstants.ACTION);
            if (action.equalsIgnoreCase(RETRIVE_RESTAURANTS)) {
                ...
                    ((AppDelegate) getApplication())
                            .setSearchResults(searchResults);
                    ListView list = (ListView) findViewById(R.id.search_result_list);
                    if (searchResults.getTotalCount() == 0) {
                        ...
                    } else {
                        if (adapter == null) {
                            adapter = new LazyListAdapter(SearchResultAbstractActivity.this, R.layout.search_item, 
                                    searchResults.getResturantList());
                            list.setAdapter(adapter);
                        } else {
                            if (list.getCount() > 0) {
                                list.setSelection(0);
                            }
                            adapter.reSet(searchResults.getResturantList());
                            list.refreshDrawableState();
                        }

                    }
                }
                ...
        }
        }
    };
};

@Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.search_result);

    Log.i("SearchResultActivity :: onStart() ",
            " ==========================I'm in start ============================");

    isNew = true;
    setTitle();
    ListView list = (ListView) findViewById(R.id.search_result_list);
    registerForContextMenu(list);

    list.setOnItemClickListener(this);
}

@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
        long id) {
        ...
}

@Override
protected void onStart() {
    super.onStart();
    ListView list = (ListView) findViewById(R.id.search_result_list);
    boolean isSet = setSearchCriteria();
    AppDelegate appDelegate = (AppDelegate) getApplication();
    if (isSet && (isNew || isFilter || searchCriteria.isNew())) {
        if (adapter != null) {
            ImageView nextBtn = (ImageView) findViewById(R.id.search_result_nextBtn);
            ImageView prevBtn = (ImageView) findViewById(R.id.search_result_prevBtn);
            TextView countTxt = (TextView) findViewById(R.id.search_result_countTxt);
            nextBtn.setVisibility(View.GONE);
            prevBtn.setVisibility(View.GONE);
            countTxt.setVisibility(View.GONE);
            adapter.clear();
            list.getEmptyView();
            searchResults.setPageNo(1);
            System.out
                    .println("%%%%%%%%%%%%%%%%%%%  Ohhhhhhh %%%%%%%%%%%%%%%%%%%%%%%");
        }
        getFilteredResturants();
        isFilter = false;
        isNew = false;
        searchCriteria.setNew(false);
    }

    if (list.getOnItemClickListener() == null) {
        Log.e("%%%%%%%%%%%%%%%%%%%  Started %%%%%%%%%%%%%%%%%%%%%%%    ",
                "" + list.getOnItemClickListener());
        list.setOnItemClickListener(this);
    }
}

@Override
protected void onDestroy() {
    System.out.println("Hi I'm signing offfffff..........");
    if (adapter != null) {
        adapter.clear();
    }
    super.onDestroy();
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    Intent previewIntend = new Intent(getApplicationContext(),
            PreviewResturant.class);
    ...
    return true;
}

protected void setNextPrevVisibility() {
    ImageView nextBtn = (ImageView) findViewById(R.id.search_result_nextBtn);
    if (searchResults.isNext()) {
        nextBtn.setVisibility(View.VISIBLE);
    } else {
        nextBtn.setVisibility(View.INVISIBLE);
    }

    ImageView prevBtn = (ImageView) findViewById(R.id.search_result_prevBtn);
    if (searchResults.isPrev()) {
        prevBtn.setVisibility(View.VISIBLE);
    } else {
        prevBtn.setVisibility(View.INVISIBLE);
    }
}

public void onPrevBtnClick(View v) {
    resetLastRestId();
    searchCriteria.setPrev(true);
    getFilteredResturants();
    searchResults.onPrev();
}

public void onNextBtnClick(View v) {
    resetLastRestId();
    searchCriteria.setPrev(false);
    getFilteredResturants();
    searchResults.onNext();
}

protected void resetLastRestId() {
    searchCriteria.setLastRestId(String.valueOf(searchResults.getResturant(
            searchResults.getResturantsCount() - 1).getId()));
}

protected void retriveResturants() {

    if (dialog == null || dialog.isShowing() == false) {

        if (((AppDelegate) getApplication())
                .isNetworkAvailable(SearchResultAbstractActivity.this)) {

            AsyncTask<Void, Void, Void> tempTask = new AsyncTask<Void, Void, Void>() {

                ProgressDialog dialog;

                protected void onPreExecute() {
                    Log.i("SearchActivity", "onPreExecute()");
                    dialog = MessageBox.showProgressDialog(
                            SearchResultAbstractActivity.this, dialog,
                            LOADING_MSG);
                    dialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
                        @Override
                        public void onCancel(DialogInterface dialog) {
                            cancel(true);
                        }
                    });

                }

                @Override
                protected Void doInBackground(Void... params) {

                    try {
                        setSearchResult();
                    } catch (SocketException e) {
                        ...
                        cancel(true);
                    } catch (SocketTimeoutException e) {
                        ...
                        cancel(true);
                    } catch (Exception e) {
                        ...
                        cancel(true);
                    }
                    return null;
                }
                @Override
                protected void onCancelled() {
                    super.onCancelled();
                    if (dialog != null && dialog.isShowing()) {
                        dialog.cancel();
                    }
                    Log.i("SearchResultAbstractActivity", "onCancelled()");
                }

                protected void onPostExecute(Void result) {
                    Message message = new Message();
                    Bundle b = new Bundle();
                    b.putString(StringConstants.ACTION, RETRIVE_RESTAURANTS);
                    message.setData(b);
                    searchResults = JSONParser.parseResturants(
                            responseString, searchResults);
                    mHandler.sendMessage(message);
                    if (dialog != null && dialog.isShowing()) {
                        dialog.dismiss();
                    }
                }
            };
            tempTask.execute();

        } else {
            MessageBox.showAlert(SearchResultAbstractActivity.this,
                    StringConstants.CONNECTION_ERROR_TITLE,
                    StringConstants.CONNECTION_ERROR_MESSAGE);
        }
    } else {
        Log.e("dialog.isShowing()  : dialog.isShowing() ",
                "dialog.isShowing()  " + dialog.isShowing());
    }

}

protected void setSearchResult() throws SoapFault, SocketException,
        Exception {
    responseString = getApiCallResponse();
}

protected String getApiCallResponse() throws SoapFault, SocketException,
        Exception {
    // try {
    return new SyncApiSoapCall(getApplicationContext(),
            StringConstants.URL_RESTAURANTS,
            StringConstants.METHOD_SEARCH_RESTAURANTS).callSearchApi(this,
            searchCriteria);
}

@Override
public void onCreateContextMenu(ContextMenu menu, View v,
        ContextMenuInfo menuInfo) {
        ...
}


@Override
public boolean onContextItemSelected(MenuItem item) {
    ...
}

@Override
public void onContextMenuClosed(Menu menu) {
    ...
    super.onContextMenuClosed(menu);
}

private boolean getFilteredResturants() {
    MyLocationListener locationListener = ((AppDelegate) getApplication())
            .getLocationListener();
    Setting setting = ((AppDelegate) getApplication()).getSetting();
    boolean isValid = false;
    try {
        if ((setting.getGps() == 1 || searchCriteria.isNearMe())
                && searchCriteria.getIsLwp() == 0
                && searchCriteria.isFavourites() == false
                && (locationListener.getLatitude().equals(
                        StringConstants.DEFAULT_LAT_LONG) || locationListener
                        .getLongitude().equals(
                                StringConstants.DEFAULT_LAT_LONG))) {
            AlertDialog.Builder builder = new AlertDialog.Builder(
                    SearchResultAbstractActivity.this);

            builder.setMessage(StringConstants.MSG_LOCATION_ERROR)
                    .setTitle(StringConstants.MSG_TITLE_LOCATION_ERROR)
                    .setCancelable(false)
                    .setPositiveButton(StringConstants.MSG_OK_TEXT,
                            new DialogInterface.OnClickListener() {
                                public void onClick(DialogInterface dialog,
                                        int id) {
                                    retriveResturants();
                                }
                            });

            AlertDialog alert = builder.create();
            alert.show();
        } else {
            isValid = true;
            retriveResturants();
        }

    } catch (Exception e) {
        // finish();
    }
    return isValid;
}

public void logout() {
...
}

@Override
public void onLowMemory() {
    Log.e("abstract search page :: Low Memory", " May kill me !!!!");
    super.onLowMemory();
}
protected abstract boolean setSearchCriteria();

protected abstract void setTitle();

protected abstract int getNoResultTitle();

// protected abstract String getNoResultMsg();

}

提前致谢。

1 个答案:

答案 0 :(得分:0)

得到解决方案:我认为即使我触发notifyDataSetChanged(),我的列表也不会刷新;在LazyListAdapter(自定义适配器)的public void reSet(ArrayList resturantsCache)中,但实际上问题在于自定义适配器的实现。

我再次附加我的适配器代码,以便其他人可以获得解决方案。

适配器:

package com.topnosh.campus.util;

import java.util.ArrayList;

import android.app.Activity;
import android.content.Context;
import android.text.Html;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;

import com.topnosh.campus.AppDelegate;
import com.topnosh.campus.R;
import com.topnosh.campus.constants.StringConstants;
import com.topnosh.campus.model.Resturant;
import com.topnosh.campus.model.Setting;

public class LazyListAdapter extends ArrayAdapter<Resturant> {

public ImageLoader imageLoader;

Context context;
int layoutResourceId;

public LazyListAdapter(Context context, int layoutResourceId,
        ArrayList<Resturant> resturants) {
    super(context, layoutResourceId, resturants);
    this.layoutResourceId = layoutResourceId;
    this.context = context;
    imageLoader = new ImageLoader(context);
    setNotifyOnChange(true);
}
...
public void reSet(ArrayList<Resturant> resturantsCache) {
    clear();
    for (Resturant resturant : resturantsCache) {
        add(resturant);
    }
}

...
}

感谢所有注意到这个问题并试图提供帮助的人。