简体   繁体   English

Android Listview滚动位置

[英]Android Listview Scroll position

I have a ListView and a list view adapter. 我有一个ListView和一个列表视图适配器。 The adapter populates the ListView from a List . 适配器从List填充ListView The list view has a onScrollListener . 列表视图具有onScrollListener The problem I have is when on scroll new data are loaded to the view but the scroll bar jumps to the top of the view. 我的问题是在滚动时将新数据加载到视图中,但滚动条跳到视图顶部。

What I want is to keep the scroll position where it was! 我要保持滚动位置不变!

Any help? 有什么帮助吗? Thanks 谢谢

List View class: 列表视图类:

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

The Adpater class: 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;
    }

You are doing wrong in your GetItems and LoadMoreDataTask AsyncTask . 您在GetItemsLoadMoreDataTask AsyncTask做错了。 you are setting new adapter each time when you scroll down so when new data are loaded to the view the scroll bar jumps to the top of the view. 您每次向下滚动时都要设置新的适配器,以便在将新数据加载到视图时,滚动条跳到视图的顶部。

You need to call 你需要打电话

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

only first time then you have to only call 只有第一次,那么你只需要打电话

adapter.notifyDataSetChanged()

to update your ListView no need to set adapter each time when making new request and also you have to set OnScrollListener to ListView only one time currently new OnScrollListener is set each time when making new request. 若要更新您的ListView ,则每次发出新请求时都不需要设置适配器,并且您也必须仅将OnScrollListener设置为ListView一次,而每次发出新请求时都将设置新的OnScrollListener

您需要在适配器为null时第一次设置setAdapter或者仅在调用notifyDataSetChanged()之后第一次获取数据

Save state of listview before updating and then restore: 在更新然后还原之前,保存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);

The most Optimal Solution will 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);

Reference : Retain Scroll Position Android ListView 参考: 保留滚动位置Android ListView

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM