2013-10-03 2 views
0

У меня есть список, который я реализовал onScrollListener, поэтому, когда список достигает нижней части, загружает больше данных. Но в моем случае список загружает данные более одного раза (три раза), и я не могу найти причину этого. Так кто-то может помочь мне!Listview loadmore on scroll выполняет три раза

Вот код:

public class GameListing extends FragmentActivity implements OnScrollListener { 

    private ListView list; 
    private GameListingAdapter adapter; 
    private ArrayList<Game> games; 
    private TextView title; 
    private ImageView back, menu; 
    private SlidingMenu slidingMenu; 
    private int jsonStart = 20; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.game_listing); 
     initWidgets(); 
     list.setOnItemClickListener(new OnItemClickListener() { 
      @Override 
      public void onItemClick(AdapterView<?> arg0, View arg1, 
        int position, long arg3) { 
       Intent i = new Intent(GameListing.this, GameDetails.class); 
       i.putExtra("game_details", games.get(position)); 
       startActivity(i); 
      } 
     }); 
    } 

    @SuppressWarnings("unchecked") 
    private void initWidgets() { 
     menu = (ImageView) findViewById(R.id.game_listing_menu); 
     list = (ListView) findViewById(R.id.game_listing_list); 
     title = (TextView) findViewById(R.id.game_listing_title); 
     back = (ImageView) findViewById(R.id.game_listing_back); 
     back.setOnClickListener(new OnClickListener() { 

      @Override 
      public void onClick(View arg0) { 
       finish(); 
      } 
     }); 

     try { 
      games = (ArrayList<Game>) getIntent().getSerializableExtra(
        "selectedGames"); 
      title.setText(games.get(0).getBelongTo().toUpperCase()); 
      adapter = new GameListingAdapter(this, games); 
      list.setAdapter(adapter); 
      list.setOnScrollListener(this); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
     displayMenu(); 
    } 

    private void displayMenu() { 
     slidingMenu = new SlidingMenu(this); 
     slidingMenu.setMode(SlidingMenu.RIGHT); 
     slidingMenu.setTouchModeAbove(SlidingMenu.TOUCHMODE_FULLSCREEN); 
     slidingMenu.setShadowWidthRes(R.dimen.slidingmenu_shadow_width); 
     slidingMenu.setShadowDrawable(R.drawable.slidingmenu_shadow); 
     slidingMenu.setBehindOffsetRes(R.dimen.slidingmenu_offset); 
     slidingMenu.setFadeDegree(0.35f); 
     slidingMenu.attachToActivity(this, SlidingMenu.SLIDING_CONTENT); 
     slidingMenu.setMenu(R.layout.slidingmenu); 

     menu.setOnClickListener(new OnClickListener() { 

      @Override 
      public void onClick(View v) { 
       slidingMenu.toggle(); 
      } 
     }); 
    } 

    @Override 
    public boolean onKeyDown(int keyCode, KeyEvent event) { 
     if (keyCode == KeyEvent.KEYCODE_MENU) { 
      slidingMenu.toggle(); 
      return true; 
     } 
     return super.onKeyDown(keyCode, event); 
    } 

    @Override 
    public void onBackPressed() { 
     if (slidingMenu.isMenuShowing()) { 
      slidingMenu.toggle(); 
     } else { 
      super.onBackPressed(); 
     } 
    } 

    @Override 
    public void onScroll(AbsListView view, int firstVisibleItem, 
      int visibleItemCount, int totalItemCount) { 
     if (list.getFirstVisiblePosition() > (games.size() - 7)) { 
      try { 
       loadJSON(); 
      } catch (JSONException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 

    @Override 
    public void onScrollStateChanged(AbsListView view, int scrollState) { 
    } 

    public void loadJSON() throws JSONException { 
     AsyncTask<Void, Void, Void> task = new AsyncTask<Void, Void, Void>() { 

      @Override 
      protected void onPreExecute() { 
       super.onPreExecute(); 

      } 

      @Override 
      protected Void doInBackground(Void... params) { 
       JSONArray json = new JSONParser() 
         .getJSONFromUrl(AppConstants.JsonURL 
           + games.get(0).getBelongTo() 
           + AppConstants.JsonLimit + jsonStart + "," 
           + (jsonStart + 20)); 
       loadGamesJson(json); 
       jsonStart += 20; 
       Log.v("--", jsonStart + " jsonStart"); 
       return null; 
      } 

      @Override 
      protected void onPostExecute(Void result) { 
       super.onPostExecute(result); 
       adapter.notifyDataSetChanged(); 

      } 
     }; 
     task.execute(); 
    } 

    private void loadGamesJson(JSONArray json) { 
     try { 
      for (int i = 0; i < json.length(); i++) { 
       JSONObject gameObj = json.getJSONObject(i) 
         .getJSONObject("game"); 
       int id = gameObj.getInt("id"); 
       String name = gameObj.getString("name"); 
       String date = gameObj.getString("release_date"); 
       String timeStamp = gameObj.getString("timeStamp"); 
       String rating = gameObj.getString("rating"); 
       String description = gameObj.getString("description"); 
       String belongsTo = gameObj.getString("belongto"); 

       String publisher = gameObj.getString("publisher") 
         .replace("\"", "").replace("[", "").replace("]", ""); 

       String platform = gameObj.getString("platform") 
         .replace("\"", "").replace("[", "").replace("]", ""); 

       String genre = gameObj.getString("genre").replace("\"", "") 
         .replace("[", "").replace("]", ""); 

       String developer = gameObj.getString("developer") 
         .replace("\"", "").replace("[", "").replace("]", ""); 
       String video = ""; 
       for (int n = 1; n <= 3; n++) { 
        video += gameObj.getString("video" + n) + ","; 
       } 

       video = video.substring(0, video.length() - 1); 
       String gameImage = gameObj.getString("game_img"); 
       games.add(new Game(id, name, date, timeStamp, rating, 
         description, publisher, gameImage, developer, platform, 
         genre, belongsTo, video, false)); 
      } 

     } catch (JSONException e) { 
      e.printStackTrace(); 
     } 
    } 

} 
+0

У меня была такая же проблема и решена путем добавления boolean, чтобы проверить, завершен ли loadJSON. – Prasad

+0

Я обнаружил то же самое. Это убивало производительность моего приложения. Я закончил тем, что написал свой собственный класс ListView, который был довольно трудоемким, но устранил проблему. –

ответ

0

Я нашел решение, кажется, что-то вроде @Prasad имел в виду. Я добавил это в моем классе:

private int visibleThreshold = 5; 
     private int currentPage = 0; 
     private int previousTotal = 0; 
     private boolean loading = true; 

и это, как мой onScroll() выглядит

@Override 
    public void onScroll(AbsListView view, int firstVisibleItem, 
      int visibleItemCount, int totalItemCount) { 
     if (loading) { 
      if (totalItemCount > previousTotal) { 
       loading = false; 
       previousTotal = totalItemCount; 
       currentPage++; 
      } 
     } 
     if (!loading 
       && (totalItemCount - visibleItemCount) <= (firstVisibleItem + visibleThreshold)) { 
      // I load the next page of gigs using a background task, 
      // but you can call any function here. 
      try { 
       loadJSON(); 
      } catch (JSONException e) { 
       e.printStackTrace(); 
      } 
      loading = true; 
     } 

    } 

и установить загрузку быть false в AsyncTask в то время как новый JSON загружается. Также я хотел бы взглянуть на this.