2017-07-08 9 views
0

これは非常に良い問題の説明ではありませんが、私はListAdapterの不安定な動作に遭遇しました。onClickListenerは数回クリックするだけで動作します

私のアプリケーションのonItemClickListenerは、激しくクリックしたときにのみ応答します。デバッガは、このような状況でのみ応答します。それにもかかわらず、時々クリックは正常に機能します。それは、何かが内部的にonItemClickListenerが呼び出されることを妨げるものがあるようです。場合によっては、デフォルトのアンドロイドクリックアニメーションが最初のクリックで表示されないこともあります。しかし、2〜5回のクリック後、次々と次々と期待どおりに動作します。

Android開発には初めてのため、どこから問題を探し始めるかわかりません。問題はデバイス固有ではありません(テスト済み)。

念のため、私のプロジェクトからいくつかのコード(私が提供して何にもわからないが):

OffersListAdapterからいくつかのコード:MainActivityから

class ViewHolder { 
    private TextView whoandWhom; 
    private TextView date; 
    private TextView distance; 

    private TextView status; 
    private TextView place; 

    private boolean isMeeting = false; 
    private Meeting.Status meetingStatus; 

    private void color(int color) { 
     for (Field v: this.getClass().getDeclaredFields()) { 
      try { 
       if (v.getType() == TextView.class) { 
        TextView view = (TextView) v.get(this); 
        view.setTextColor(res.getColor(color)); 
       } 
      } catch (IllegalAccessException e) { 
       Log.e("ERROR", "This field does not exist"); 
      } 
     } 
    } 
} 
private View prepareHolder(boolean isMeeting, View convertView, Meeting.Status mStatus, Offer offer) { 
    ViewHolder holder = new ViewHolder(); 

    LayoutInflater li = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    if (isMeeting) { 
     convertView = li.inflate(R.layout.meetings_item, null); 
    } else { 
     convertView = li.inflate(R.layout.offers_item, null); 
    } 
    holder.whoandWhom = (TextView)convertView.findViewById(R.id.datetime); 
    holder.date = (TextView)convertView.findViewById(R.id.dateTime); 
    holder.distance = (TextView)convertView.findViewById(R.id.distance); 

    if (isMeeting) { 
     holder.isMeeting = true; 
     holder.status = (TextView)convertView.findViewById(status); 
     holder.place = (TextView)convertView.findViewById(place); 
     holder.meetingStatus = mStatus; 
    } 

    convertView.setTag(holder); 

    holder.whoandWhom.setText(offer.getOwnership()); 
    holder.date.setText(offer.getDateRepresentation()); 
    String distance = new DecimalFormat("#####.##").format(offer.getDistance()) + " км"; 
    holder.distance.setText(distance); 

    if (isMeeting) { 
     Meeting meeting = (Meeting) offer; 
     holder.place.setText(meeting.getPlace_name()); 
     switch (meeting.getStatus()) { 
      case pending: 
       holder.status.setText("Очікує підтвердження"); 
       break; 
      case upcoming: 
       holder.status.setText("Незабаром"); 
       holder.color(R.color.colorAccent); 
       break; 
      case completed: 
       holder.status.setText("Завершено"); 
       holder.color(R.color.colorPrimary); 
       break; 
     } 
    } 

    return convertView; 
} 

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 

    ViewHolder holder; 
    Offer offer = this.getItem(position); 
    Boolean isMeeting = offer.getClass() == Meeting.class; 

    Meeting.Status status = null; 
    if (isMeeting) 
     status = ((Meeting) offer).getStatus(); 

    if (convertView == null) { 
     convertView = prepareHolder(isMeeting, convertView, status, offer); 
    } else { 
     holder = (ViewHolder) convertView.getTag(); 
     if (isMeeting != holder.isMeeting) 
      convertView = prepareHolder(isMeeting, convertView, status, offer); 
     else if (isMeeting) { 
      if (status != holder.meetingStatus) 
       convertView = prepareHolder(true, convertView, status, offer); 
     } 
    } 

    return convertView; 
} 

いくつかの方法:

private void configureOffersOutput() { 
    offersOutput = (ListView) findViewById(R.id.offersOutput); 
    offersList = new ArrayList<Offer>(); 

    LayoutInflater li = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    loadingView = li.inflate(R.layout.list_footer_view, null); 

    adapter = new OffersListAdapter(getApplicationContext(), offersList, getResources()); 

    configureOnItemClick(); 
    offersOutput.setAdapter(adapter); 

    offersOutput.setNestedScrollingEnabled(true); 
    offersOutput.setOnScrollListener(new AbsListView.OnScrollListener() { 
     @Override 
     public void onScrollStateChanged(AbsListView view, int scrollState) {} 
     @Override 
     public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { 
      if (view.getLastVisiblePosition() >= totalItemCount - 1 && !isLoading) { 
       moreOffers(); 
      } 
     } 
    }); 
} 


private void configureOnItemClick() { 

    final Activity a = this; 

    offersOutput.setOnItemClickListener(new AdapterView.OnItemClickListener() { 
     @Override 
     public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 
      final Offer item = offersList.get(position); 
      if (item.getClass() == Offer.class) { 

       openActivity(a, SuggestActivity.class, new HashMap<String, String>() {{ 
        put("id", item.getId()); 
        put("location", item.getLocation()); 
        put("datetime", item.getDateRepresentation()); 
        put("ownership", item.getOwnership()); 

        put("currentCoordinates", coordinates); 
        put("token", user.getToken()); 
        put("uid", user.getId()); 
       }}); 

      } else if (item.getClass() == Meeting.class) { 

       final Meeting meeting = (Meeting) item; 
       Class<?> name; 

       switch (meeting.getStatus()) { 
        case pending: 
         name = ApproveActivity.class; 
         break; 
        case upcoming: 
         name = UpcomingActivity.class; 
         break; 
        case completed: 
         name = RateActivity.class; 
         break; 
        default: 
         name = MeetingActivity.class; 
         Log.e("ERROR", "Wrong status: " + meeting.getStatus().toString()); 
       } 

       final String distance = new DecimalFormat("#####.##").format(meeting.getDistance()) + " км"; 

       openActivity(a, name, new HashMap<String, String>(){{ 
        put("id", meeting.getId()); 
        put("datetime", meeting.getDateRepresentation()); 
        put("ownership", meeting.getOwnership()); 

        put("tel", meeting.getTel()); 
        put("distance", distance); 
        put("place", meeting.getPlace_name()); 
        put("place_coordinates", meeting.getPlace_coordinates()); 

        put("currentCoordinates", coordinates); 
        put("token", user.getToken()); 
        put("uid", user.getId()); 
       }}); 

      } 
     } 
    }); 

    initRefresh(); 

    isSetItemOnClick = true; 
} 
+0

あなたのonclickリスナーは –

+0

あなたに投稿してくださいonClickListener、 これは私には以前起こっていました。アクティビティから2つのリスナーを実装し、同じビューのアダプタから2つのリスナーを実装したからです。 –

+0

offerOutput.setonItemClickListerner? – Jamil

答えて

0

わかりました同じ問題があります。

これ以外にも、スクロールイベントに応答するメソッドがありました。それはこのようにスクロール上のデータをダウンロードします:

ffersOutput.setNestedScrollingEnabled(true); 
    offersOutput.setOnScrollListener(new AbsListView.OnScrollListener() { 
     @Override 
     public void onScrollStateChanged(AbsListView view, int scrollState) {} 
     @Override 
     public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { 
      if (view.getLastVisiblePosition() >= totalItemCount - 1 && !isLoading) { 
       moreOffers(); 
      } 
     } 
    }); 

moreOffersがよりバックエンドと行をロードするための要求を送信します。

問題があった。

  1. それはアプリケーションがこんなに早くリクエストを送信し、そう頻繁に時間wouldn」は、彼らが最も行をリフレッシュしようとした空の結果
  2. を受け取ることになるので、DBは、非常に迅速に行を使い果たしタッチに反応することができます。

ソリューション(醜いものの): このようなDB何かからのデータを受信する方法に追加しますので、頻繁に要求を行うことから、アプリを防ぎ、それが応答することができます

new Timer().schedule(new TimerTask() { 
    @Override 
    public void run() { 
     isLoading = false; 
    } 
}, 100); 

関連する問題