2015-10-05 69 views
0

我有一個ListView和一個列表視圖適配器。適配器從List填充ListView。列表視圖有一個onScrollListener。我遇到的問題是當滾動新數據加載到視圖,但滾動條跳轉到視圖的頂部。Android Listview Scroll position

我想要的是保持滾動位置在哪裏!

任何幫助? 感謝

列表視圖類:

private class GetItems extends AsyncTask<Void, Void, Void> 
{ 
    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 

     // Create a progressdialog 
     mProgressDialog = new ProgressDialog(AppList.this); 
     // Set progressdialog title 
     mProgressDialog.setTitle("Loading more"); 
     mProgressDialog.setMessage("loading); 
     mProgressDialog.setIndeterminate(false); 
     // Show progressdialog 
     mProgressDialog.show(); 
    } 

    @Override 
    protected Void doInBackground(Void... params) 
    { 
     applicationList = new ArrayList(); 

     try 
     { 
      GetDataAppList getDataAppList = new GetDataAppList(); 
      JSONArray jsonData = getDataAppList.getJSONData(webfileName, limit, offset); 

      for (int i = 0; i <= jsonData.length() - 2; i++) 
      { 
       JSONObject c = jsonData.getJSONObject(i); 

       id = c.getString("id"); 
       name = c.getString("name"); 
       logo = c.getString("logo"); 
       developer = c.getString("developer"); 
       rate = c.getInt("rates"); 
       category = c.getInt("category"); 
       fileName = c.getString("filename"); 
       path = c.getString("path"); 
       appSize = c.getDouble("size"); 

       if(category == 1001) 
       { 
        String gCat = c.getString("game_category"); 
        applicationList.add(new ApplicationPojo(id,name,logo,developer,appSize,category,fileName,path,gCat)); 
       } 
       else 
       { 
        applicationList.add(new ApplicationPojo(id,name,logo,developer,appSize,category,fileName,path)); 

       } 
      } 
      JSONObject sizeObj = jsonData.getJSONObject(jsonData.length() - 1); 
      size = sizeObj.getInt("size"); 


     } 
     catch (Exception ex) 
     { 
      Log.d("Thread:", ex.toString()); 
     } 

     return null; 
    } 

    @Override 
    protected void onPostExecute(Void result) 
    { 
     // Locate the ListView in listview.xml 
     listview = (ListView) findViewById(R.id.listView); 
     // Pass the results into ListViewAdapter.java 
     adapter = new ListViewAdapter(AppList.this, applicationList,listview); 
     // Binds the Adapter to the ListView 
     listview.setAdapter(adapter); 
     // Close the progressdialog 
     mProgressDialog.dismiss(); 
     // Create an OnScrollListener 

     listview.setOnScrollListener(new OnScrollListener() { 

      @Override 
      public void onScrollStateChanged(AbsListView view, int scrollState) { 
       int threshold = 1; 
       int count = listview.getCount(); 

       if (scrollState == SCROLL_STATE_IDLE) { 
        if (listview.getLastVisiblePosition() >= count - threshold) { 
         if (size >= offset) 
         { 
          new LoadMoreDataTask().execute(); 
          offset = offset + 15; 
         } 
         else 
         { 
          Toast.makeText(getApplicationContext(), "ختم لست!", Toast.LENGTH_LONG).show(); 

         } 
        } 
       } 
      } 

      @Override 
      public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { 
       // TODO Auto-generated method stub 

      } 

     }); 

     RatingBar bar = (RatingBar) findViewById(R.id.ratingBarShow); 

    } 
} 

private class LoadMoreDataTask extends AsyncTask<Void, Void, Void> { 
    @Override 
    protected void onPreExecute() { 
     super.onPreExecute(); 
     mProgressDialog = new ProgressDialog(AppList.this); 
     mProgressDialog.setTitle("Loading more"); 
     mProgressDialog.setMessage("loading); 
     mProgressDialog.setIndeterminate(false); 
     mProgressDialog.show(); 
    } 

    @Override 
    protected Void doInBackground(Void... params) 
    { 
     try 
     { 
      GetDataAppList getDataAppList = new GetDataAppList(); 

      JSONArray jsonData = getDataAppList.getJSONData(webfileName, limit, offset); 

      for (int i = 0; i <= jsonData.length(); i++) { 
       JSONObject c = jsonData.getJSONObject(i); 

       id = c.getString("id"); 
       name = c.getString("name"); 
       logo = c.getString("logo"); 
       developer = c.getString("developer"); 
       rate = c.getInt("rates"); 
       category = c.getInt("category"); 
       fileName = c.getString("filename"); 
       path = c.getString("path"); 
       appSize = c.getDouble("size"); 

       if(category == 1001) 
       { 
        String gCat = c.getString("game_category"); 
        applicationList.add(new ApplicationPojo(id,name,logo,developer,appSize,category,fileName,path,gCat)); 
       } 
       else 
       { 
        applicationList.add(new ApplicationPojo(id,name,logo,developer,appSize,category,fileName,path)); 

       } 

      } 
     } 
     catch (Exception ex) 
     { 

     } 
     return null; 
    } 

    @Override 
    protected void onPostExecute(Void result) 
    { 

     int position = listview.getLastVisiblePosition(); 

     adapter = new ListViewAdapter(AppList.this, applicationList,listview); 


     listview.setAdapter(adapter); 

     listview.setSelectionFromTop(position, 0); 

     mProgressDialog.dismiss(); 
    } 
} 

的Adpater類:列表視圖的

public ListViewAdapter(Activity activity, ArrayList<ApplicationPojo> applicationList, ListView listView) 
    { 
     this.activity = activity; 
     this.applicationList = applicationList; 
     this.inflater = LayoutInflater.from(activity); 
     downloader = new ApkFileDownloader(activity); 
     this.listView = listView; 
    } 

    @Override 
    public int getCount() { 
     return applicationList.size(); 
    } 

    @Override 
    public ApplicationPojo getItem(int position) { 
     return applicationList.get(position); 
    } 

    @Override 
    public long getItemId(int position) { 
     return position; 
    } 

    public View getView(final int position, View view, ViewGroup parent) 
    { 
     if (view == null) 
     { 
      holder = new ViewHolder(); 
      view = inflater.inflate(R.layout.singleapp, null); 

      holder.openInstalledAppBtn = (ImageView) view.findViewById(R.id.openInstalledApp); 
      holder.downloadBtn = (ImageView) view.findViewById(R.id.updateApp); 
      holder.progressBar = (ProgressBar)view.findViewById(R.id.updateProgress); 
      holder.cancelBtn = (ImageView) view.findViewById(R.id.cancel); 
      holder.appName = (TextView) view.findViewById(R.id.appName); 
      holder.developer = (TextView) view.findViewById(R.id.developer); 
      holder.size = (TextView) view.findViewById(R.id.size); 
      holder.appCat = (TextView) view.findViewById((R.id.appCat)); 
      holder.installBtn = (ImageView) view.findViewById(R.id.install); 
      holder.catlogo = (ImageView) view.findViewById(R.id.catlogo); 


      view.setTag(holder); 
     } 
     else 
     { 
      holder = (ViewHolder) view.getTag(); 
     } 

     try 
     { 
      final View finalView = view; 

      holder.logo = (ImageView) finalView.findViewById(R.id.appLogo); 
      logoName = applicationList.get(position).getLogo(); 

      Picasso.with(activity) 
        .load(IPClass.SERVERIP + logoName) 
        .into(holder.logo); 

//   holder.logo.setOnClickListener(new View.OnClickListener() { 
//    @Override 
//    public void onClick(View arg0) { 
// 
//    } 
//   }); 

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

        String appid = applicationList.get(position).getId(); 
        int category = applicationList.get(position).getCategory(); 

        Intent rec1Intent = new Intent(activity, AppView.class); 
        activity.startActivity(rec1Intent); 

        AppView appView = new AppView(); 
        appView.setParameters(appid, category); 

        AppList.adapter.notifyDataSetChanged(); 
       } 
      }); 

      final String id = applicationList.get(position).getId(); 
      final String path = applicationList.get(position).getPath(); 
      final String fileName = applicationList.get(position).getFileName(); 
      final String name = applicationList.get(position).getName(); 
      final String developer = applicationList.get(position).getDeveloper(); 
      final double size = applicationList.get(position).getSize(); 
      final String logo = applicationList.get(position).getLogo(); 
      final int category = applicationList.get(position).getCategory(); 

      final String appName = applicationList.get(position).getFileName(); 
      String checkAppInstalled = appName.substring(0,appName.length() - 4); 

      //------------CHECK IF APPLICATION IS INSTALLED ---------------------------------------- 

      if(appInstalled(checkAppInstalled)) 
      { 
       holder.downloadBtn.setVisibility(View.GONE); 
       holder.cancelBtn.setVisibility(View.GONE); 
       holder.progressBar.setVisibility(View.GONE); 
       holder.installBtn.setVisibility(View.GONE); 

       holder.openInstalledAppBtn.setVisibility(View.VISIBLE); 
       holder.openInstalledAppBtn.setOnClickListener(new View.OnClickListener() 
       { 
        @Override 
        public void onClick(View v) { 

         String fileName = (applicationList.get(position).getFileName()); 
         String appToOpen = fileName.substring(0,fileName.length() - 4); 

         Context ctx = activity.getApplicationContext(); 
         Intent mIntent = ctx.getPackageManager().getLaunchIntentForPackage(appToOpen); 
         String mainActivity = mIntent.getComponent().getClassName(); 

         Intent intent = new Intent("android.intent.category.LAUNCHER"); 
         intent.setClassName(appToOpen, mainActivity); 
         activity.startActivity(intent); 
        } 
       }); 
      } 

      //------------- IF APPLICATION IS NOT ALREADY INSTALLED -------------------------------- 

      else 
      { 
       //------------------------ CHECK IF APK EXISTS ------------------------------------- 

       String filePath = Environment.getExternalStorageDirectory().toString(); 
       File file = new File(filePath + "/appsaraai/" + fileName); 

       if(file.exists()) 
       { 
        holder.downloadBtn.setVisibility(View.GONE); 
        holder.cancelBtn.setVisibility(View.GONE); 
        holder.openInstalledAppBtn.setVisibility(View.GONE); 
        holder.progressBar.setVisibility(View.GONE); 

        holder.installBtn.setVisibility(View.VISIBLE); 
        holder.installBtn.setOnClickListener(new View.OnClickListener() { 
         @Override 
         public void onClick(View v) { 
          Intent intent = new Intent(Intent.ACTION_VIEW); 
          intent.setDataAndType(Uri.fromFile(new File(Environment.getExternalStorageDirectory() + "/appsaraai/" + fileName)), "application/vnd.android.package-archive"); 
          activity.startActivity(intent); 

          for (int i = 0; i < DownloadLists.list.size(); i++) { 

           if (DownloadLists.list.get(i).getName().equals(name)) { 
            DownloadLists.list.remove(i); 
           } 
          } 
         } 
        }); 

        AppList.adapter.notifyDataSetChanged(); 
       } 

       //------------------ IF APK DOES NOT EXIST ----------------------------------------- 
       else 
       { 
        //-----CHECK IF DOWNLOAD IS IN PROGRESS ---------------------------------------- 

        if (ApkFileDownloader.applicationList.containsKey(name)) 
        { 
         holder.downloadBtn.setVisibility(View.GONE); 
         holder.installBtn.setVisibility(View.GONE); 
         holder.openInstalledAppBtn.setVisibility(View.GONE); 

         new ApkFileDownloader(activity).getDownloadStatus(holder.progressBar, name, holder.installBtn, holder.cancelBtn); 

         holder.progressBar.setVisibility(View.VISIBLE); 
         holder.cancelBtn.setVisibility(View.VISIBLE); 

         holder.cancelBtn.setOnClickListener(new View.OnClickListener() { 
          @Override 
          public void onClick(View v) { 
           downloader.cancelDownload(name); 
           holder.cancelBtn.setVisibility(View.GONE); 
           holder.downloadBtn.setVisibility(View.VISIBLE); 
           DownloadLists dlist = new DownloadLists(activity); 
           dlist.deleteData(name); 

           try { 
            AppList.adapter.notifyDataSetChanged(); 
           } catch (Exception ex) { 
            System.out.println(ex); 

           } 

           try 
           { 
            SearchResult.adapter.notifyDataSetChanged(); 
           } 
           catch (Exception ex) 
           { 
            System.out.println(ex); 
           } 
          } 
         }); 
        } 

        //-------------- IF DOWNLOAD IS NOT IN PROGRESS START NEW DOWNLOAD ------------- 
        else 
        { 
         holder.progressBar.setVisibility(View.GONE); 
         holder.cancelBtn.setVisibility(View.GONE); 
         holder.installBtn.setVisibility(View.GONE); 
         holder.openInstalledAppBtn.setVisibility(View.GONE); 

         holder.downloadBtn.setVisibility(view.VISIBLE); 
         holder.downloadBtn.setOnClickListener(new View.OnClickListener() { 
          @Override 
          public void onClick(View arg0) { 

           holder.downloadBtn.setVisibility(View.GONE); 
           holder.cancelBtn.setVisibility(View.VISIBLE); 
           holder.cancelBtn.setOnClickListener(new View.OnClickListener() { 
            @Override 
            public void onClick(View v) { 
             downloader.cancelDownload(name); 
             holder.cancelBtn.setVisibility(View.GONE); 
             holder.downloadBtn.setVisibility(View.VISIBLE); 

             try { 
              AppList.adapter.notifyDataSetChanged(); 
             } catch (Exception ex) { 
              System.out.println(ex); 

             } 
             try { 
              SearchResult.adapter.notifyDataSetChanged(); 
             } catch (Exception ex) { 
              System.out.println(ex); 
             } 
            } 
           }); 

           new Thread(new Runnable() { 
            @Override 
            public void run() { 

             try { 
              Bitmap logoImg = Picasso.with(activity).load(IPClass.SERVERIP + logo).get(); 
              DownloadLists.list.add(new ApplicationPojo(id, name, developer, size, logoImg, holder.progressBar)); 
              DownloadLists dlist = new DownloadLists(activity); 
              dlist.insertData(id, name, developer, size, fileName, logoImg); 
              UpdateServerDownload d = new UpdateServerDownload(); 
              d.updateDownloadNo(id, category); 
             } catch (IOException e) { 
              e.printStackTrace(); 
             } 
            } 
           }).start(); 

           new ApkFileDownloader(activity).setParameters(path, fileName, name); 

           try { 
            AppList.adapter.notifyDataSetChanged(); 
           } catch (Exception ex) { 
            System.out.println(ex); 
           } 

           try { 
            SearchResult.adapter.notifyDataSetChanged(); 
           } catch (Exception ex) { 
            System.out.println(ex); 
           } 
          } 
         }); 
        } 
       } 
      } 

      holder.appName.setText(applicationList.get(position).getName()); 
      holder.developer.setText(applicationList.get(position).getDeveloper()); 
      String sizeText = " میگابایت "; 
      String appSize =String.valueOf(applicationList.get(position).getSize()) + sizeText; 
      holder.size.setText(appSize); 

      if(category == 1001) 
      { 
       String cat = applicationList.get(position).getgCat(); 
       holder.appCat.setText(" " + returnGameCat(cat)); 
       holder.catlogo.setImageResource(R.drawable.gamecatlogo); 
      } 



     } 
     catch (Exception ex) 
     { 
      Log.d("Adapter Exception", ex.toString()); 
     } 

     return view; 
    } 

    //--------------- A METHOD TO CHECK IF APPLICATION IS ALREADY INSTALLED ------------------------ 
    public boolean appInstalled(String checkApp) 
    { 
     pm = activity.getPackageManager(); 

     try 
     { 
      pm.getPackageInfo(checkApp, PackageManager.GET_ACTIVITIES); 
      isAppInstalled = true; 
     } 
     catch (PackageManager.NameNotFoundException e) 
     { 
      isAppInstalled = false; 
     } 

     return isAppInstalled; 
    } 
+1

顯示你的代碼。 – Rajesh

+0

這個問題有許多最佳解決方案,但標準只是將您的新數據添加到原始列表並通知適配器,而不是在每個新數據請求上分配新適配器。 –

回答

1

你在你的GetItemsLoadMoreDataTaskAsyncTask做錯了。每次向下滾動時都要設置新的適配器,因此當新數據加載到視圖時,滾動條跳轉到視圖的頂部。

你需要調用

adapter = new ListViewAdapter(AppList.this, applicationList,listview); 
listview.setAdapter(adapter); 

只有第一次,那麼你必須只調用

adapter.notifyDataSetChanged() 

更新您的ListView無需每次都設置適配器製造新的請求時,你也有將OnScrollListener設置爲ListView當前只有一次新的OnScrollListener在每次發出新的請求時被設置。

+0

謝謝親愛的工作! – Shoaib

+0

@瑪麗,不客氣。 – Rajesh

+0

@瑪麗,這是我在我的評論中說的,但我認爲你沒有看到我的評論任何方式祝你好運。 –

0

保存狀態更新,然後才恢復:

// save index and top position 
int index = mListView.getFirstVisiblePosition(); 
View v = mListView.getChildAt(0); 
int top = (v == null) ? 0 : v.getTop(); 

// notify dataset changed or re-assign adapter here 

// restore the position of listview 
mListView.setSelectionFromTop(index, top); 
0

最優化的解決方案be

// Save the ListView state (= includes scroll position) as a Parceble 
Parcelable state = listView.onSaveInstanceState(); 

// e.g. set new items 
listView.setAdapter(adapter); 

// Restore previous state (including selected item index and scroll position) 
listView.onRestoreInstanceState(state); 

參考:Retain Scroll Position Android ListView

1

你需要setAdapter第一次當適配器爲空或正在獲取數據後第一時間就只需要調用notifyDataSetChanged()