Android Listview滚动位置

时间:2015-10-05 04:44:58

标签: android listview

我有一个ListView和一个列表视图适配器。适配器从ListView填充List。列表视图有onScrollListener。我遇到的问题是当滚动新数据加载到视图但滚动条跳转到视图的顶部。

我想要的是保持滚动位置!

有任何帮助吗? 感谢

列表视图类:

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

4 个答案:

答案 0 :(得分:1)

您的GetItemsLoadMoreDataTask AsyncTask出错了。每次向下滚动时都要设置新的适配器,这样当新数据加载到视图时,滚动条会跳到视图的顶部。

您需要致电

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

只有第一次你必须只打电话

adapter.notifyDataSetChanged()

更新ListView每次发出新请求时都不需要设置适配器,而且您必须将OnScrollListener设置为ListView,目前新OnScrollListener只有一次每次提出新请求时设置。

答案 1 :(得分:1)

当适配器为空或第一次在调用setAdapter之后第一次获取数据时,您需要notifyDataSetChanged()

答案 2 :(得分:0)

在更新之前保存listview的状态,然后恢复:

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

答案 3 :(得分:0)

最佳解决方案将是

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