【问题标题】:Android ListView showing only first 4 items on repeatAndroid ListView 仅重复显示前 4 个项目
【发布时间】:2015-02-17 16:38:05
【问题描述】:

我有一个名为 用户管理 的片段,我从服务器收集数据并将其显示在 ListView 中。也可以通过SwipeRefreshLayout 刷新。

发生的情况是,如果我获得 1-4 个用户的数据,它会正确显示数据。但是,如果我获取超过 4 个用户的数据,它会正确显示前 4 个,而不是第 5 个,而是第一个,而不是第 6 个,它是第二个,依此类推。

我已经尝试了我能想到的一切,适配器正确获取数据,ListView 正确获取适配器,但由于某种原因,它在显示 4 个用户时达到峰值,然后简单地重复它们(有趣问题是,如果我添加一个用户然后刷新,它只是在列表中重复下一个用户一次,所以它肯定知道用户数的变化)

你能帮我找出问题吗?

java 类:

package com.softwarenation.jetfuel.fragments.userManagement;

import android.app.AlertDialog;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.ListFragment;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.widget.SwipeRefreshLayout;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.android.volley.VolleyError;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.handmark.pulltorefresh.library.PullToRefreshBase;
import com.handmark.pulltorefresh.library.PullToRefreshListView;
import com.softwarenation.jetfuel.R;
import com.softwarenation.jetfuel.activities.MainActivity;
import com.softwarenation.jetfuel.fragments.Stations;
import com.softwarenation.jetfuel.managers.JetfuelManager;
import com.softwarenation.jetfuel.managers.StatusManager;
import com.softwarenation.jetfuel.managers.UserManager;
import com.softwarenation.jetfuel.utility.Global;
import com.softwarenation.jetfuel.utility.GlobalConnection;
import com.softwarenation.jetfuel.utility.users.User_pictures;
import com.softwarenation.jetfuel.utility.users.Users_mana;

import org.nicktate.projectile.Method;
import org.nicktate.projectile.Projectile;
import org.nicktate.projectile.StringListener;

import java.io.InputStream;
import java.util.ArrayList;


public class UserManagement extends Fragment {
    private SwipeRefreshLayout swipeRefreshLayout;
    //private View refreshView;
    private Global font = new Global();
    private ListView listView;
    private ArrayList<User_pictures> pictureses = new ArrayList<User_pictures>();
    private static boolean isfirst = false;


    private PullToRefreshListView pullToRefreshView;

    /**---------------------------------------------------------------------------------------------*/
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setHasOptionsMenu(true);

    }



    /**---------------------------------------------------------------------------------------------*/


    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.fragment_usermanagemnet, container, false);
        listView = (ListView)rootView.findViewById(R.id.list);
        swipeRefreshLayout = (SwipeRefreshLayout)rootView.findViewById(R.id.swipe);
      //  refreshView = (View) rootView.findViewById(R.id.swipe);

        //First time, we get the data from a server, then only display that data until the user calls for a refresh
        if(!StatusManager.getInstance().getUsermStatus()){
            UsersTask usersTask = new UsersTask();
            usersTask.execute();
        }else{
            setContent();
        }



        Button addUser = (Button)rootView.findViewById(R.id.addUser_button);
        addUser.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Fragment fragment = new AddUser();
                FragmentManager fragmentManager = getFragmentManager();
                fragmentManager.beginTransaction().replace(R.id.content_frame, fragment).commit();
            }
        });


        // Set a listener to be invoked when the list should be refreshed.




        swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
                                                            @Override
                                                            public void onRefresh() {
                                                                Log.e("start","onRefresh");
                                                                new GetDataTask().execute();
                                                            }
                                                        }
        );










       /* pullToRefreshView = (PullToRefreshListView)rootView.findViewById(R.id.pull_to_refresh_listview);
        pullToRefreshView.bringToFront();
        pullToRefreshView.setOnRefreshListener(new PullToRefreshBase.OnRefreshListener<ListView>() {
            @Override
            public void onRefresh(PullToRefreshBase<ListView> refreshView) {
                // Do work to refresh the list here.
                new GetDataTask().execute();
            }
        });*/

        return rootView;
    }


public void setOnRefreshListener (SwipeRefreshLayout.OnRefreshListener listener){
    swipeRefreshLayout.setOnRefreshListener(listener);
}

public boolean isRefreshing(){
    return swipeRefreshLayout.isRefreshing();
}


    public void setRefreshing(boolean refreshing){
        swipeRefreshLayout.setRefreshing(refreshing);
    }


    public SwipeRefreshLayout getSwipeRefreshLayout(){
        return swipeRefreshLayout;
    }


    //on refresh, get new data from the server
    private class GetDataTask extends AsyncTask<Void, Void, String[]> {

        @Override
        protected String[] doInBackground(Void... voids) {Log.e("start","GetDataTask");
            UsersTask usersTask = new UsersTask();
            usersTask.execute();
            return new String[0];
        }

        @Override
        protected void onPostExecute(String[] result) {
            // Call onRefreshComplete when the list has been refreshed.
          //  pullToRefreshView.onRefreshComplete();
            super.onPostExecute(result);
            MainActivity.setBackDisabled(false);
            Log.e("GetDataTask","completed");
        }
    }






    private class SampleItem {
        public String id;
        public String title;
        public String username;
        public String groupName;
        public int userPicture;
        public int editPicture;
        public int dPicture;
        public String activated;

        public SampleItem(String id, String title, String username, String groupName, int userPicture, int editPicture, int dPicture, String activated ) {
            this.id = id;
            this.title = title;
            this.username = username;
            this.groupName = groupName;
            this.userPicture = userPicture;
            this.editPicture = editPicture;
            this.dPicture = dPicture;
            this.activated = activated;
        }

    }




    static class ViewHolder {
        private String checkBox;
        private RelativeLayout relativeLayout;
        private LinearLayout linearLayout;
        private RelativeLayout relativeLayout2;

        public void setCheckBox(String checkBox) {
            this.checkBox = checkBox;
        }

        public void setLinearLayout(LinearLayout linearLayout) {
            this.linearLayout = linearLayout;
        }

        public void setRelativeLayout(RelativeLayout relativeLayout) {
            this.relativeLayout = relativeLayout;
        }

        public void setRelativeLayout2(RelativeLayout relativeLayout2) {
            this.relativeLayout2 = relativeLayout2;
        }

        public LinearLayout getLinearLayout() {
            return linearLayout;
        }

        public RelativeLayout getRelativeLayout() {
            return relativeLayout;
        }

        public RelativeLayout getRelativeLayout2() {
            return relativeLayout2;
        }

        public RelativeLayout getCheckBox() {
            return relativeLayout;
        }

    }



    public class SampleAdapter extends ArrayAdapter<SampleItem> {
        final ViewHolder holder = new ViewHolder();

        public SampleAdapter(Context context) {
            super(context, 0);
        }

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

            if (convertView == null) {
                convertView = LayoutInflater.from(getContext()).inflate(R.layout.row_usermana, null);


                ImageView userPicture = (ImageView)convertView.findViewById(R.id.userpicture);
                userPicture.setImageDrawable(getResources().getDrawable(getItem(position).userPicture));

                TextView title = (TextView)convertView.findViewById(R.id.user_name);
                font.setFont(title, 3, getActivity());
                title.setText(getItem(position).title);

                TextView username = (TextView)convertView.findViewById(R.id.username);
                font.setFont(username, 2, getActivity());
                username.setText(getItem(position).username);

                TextView groupname = (TextView)convertView.findViewById(R.id.groupName);
                font.setFont(groupname, 2, getActivity());
                groupname.setText(getItem(position).groupName);

                ImageView useredit = (ImageView)convertView.findViewById(R.id.editbutton);
                useredit.setImageDrawable(getResources().getDrawable(getItem(position).editPicture));
                useredit.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {

                        Bundle bundle = new Bundle();
                        bundle.putString("user_id", getItem(position).id);


                        Fragment fragment = new EditProfile();
                        fragment.setArguments(bundle);
                        FragmentManager fragmentManager = getFragmentManager();
                        fragmentManager.beginTransaction().replace(R.id.content_frame, fragment).commit();
                    }
                });

                /**---------------*/

                ImageView userdelate = (ImageView)convertView.findViewById(R.id.deletebutton);
                userdelate.setImageDrawable(getResources().getDrawable(getItem(position).dPicture));

                holder.setLinearLayout((LinearLayout)convertView.findViewById(R.id.lin_show_profile));



                //LinearLayout show = (LinearLayout)convertView.findViewById(R.id.lin_show_profile);
                holder.getLinearLayout().setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {

                        Bundle bundle = new Bundle();
                        bundle.putString("user_id", getItem(position).id);


                        Fragment fragment = new ShowProfile();
                        fragment.setArguments(bundle);
                        FragmentManager fragmentManager = getFragmentManager();
                        fragmentManager.beginTransaction().replace(R.id.content_frame, fragment).commit();
                    }
                });


                //
                holder.setRelativeLayout((RelativeLayout)convertView.findViewById(R.id.delate_user));
                //RelativeLayout delete_user = (RelativeLayout)convertView.findViewById(R.id.delate_user);
                holder.getRelativeLayout().setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        DialogStop("Are you sure?", getItem(position).username, getActivity(), getItem(position).id);

                    }
                });
                //
                //holder.setCheckBox(getItem(position).activated);
                //
                /**---------------*/
                //Red or Blue background
                // RelativeLayout settings = (RelativeLayout)convertView.findViewById(R.id.settingsbutton);
                holder.setRelativeLayout2((RelativeLayout) convertView.findViewById(R.id.settingsbutton));

                //if(getItem(position).activated.equals("false")) {

                if (getItem(position).activated.equals("false")) {
                    holder.getLinearLayout().setBackground(getResources().getDrawable(R.drawable.discrepancy_background_red));
                    holder.getRelativeLayout().setBackground(getResources().getDrawable(R.drawable.discrepancy_background_red));
                    holder.getRelativeLayout2().setBackground(getResources().getDrawable(R.drawable.discrepancy_background_red));

                }

                //holder.setCheckBox(getItem(position).activated);
                convertView.setTag(holder);

            } else {

                convertView.getTag();

            }


            return convertView;
        }

    }




    public void DialogStop(String title, String message,Context context, final String id){
        new AlertDialog.Builder(context)
                .setTitle(title)
                .setMessage(message)
                .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        //dialog.cancel();

                        DeleteTask deleteTask = new DeleteTask();
                        deleteTask.execute(id);
                    }
                })
                .setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.cancel();

                    }
                })
                .setIcon(android.R.drawable.ic_dialog_alert)
                .show();
    }



    private class DeleteTask extends AsyncTask<String, String, String>{

        @Override
        protected String doInBackground(String... params) {
            String response = null;

            try {
                response = new GlobalConnection().DELETE( getString(R.string.apicdeleteuser) + params[0].toString() );
                Log.v("response", response + "");
            } catch (Exception e) {
                e.printStackTrace();
            }

            return response;
        }

        @Override
        protected void onPostExecute(String response) {
            Log.v("response", response + "");
        }
    }








    private class UsersTask extends AsyncTask<String, Void, ArrayList<Users_mana>> {

        @Override
        protected ArrayList<Users_mana> doInBackground(String... strings) {
            //Users_mana users = null;
            String response = null;
            ArrayList<Users_mana> users_manas = null;

            try{Log.e("start","GET via GlobalConnection()");
                response = new GlobalConnection().GET( getString(R.string.apiusers));
                users_manas = new Gson().fromJson(response, new TypeToken<ArrayList<Users_mana>>(){}.getType());
                Log.e("start","setUsers_mana");
                UserManager.getInstance().setUsers_mana(users_manas);


            }catch (Exception e){
                Log.e("response error", e.getMessage().toString());
            }

            return users_manas;
        }


        @Override
        protected void onPostExecute(ArrayList<Users_mana> response) {

            if(!response.isEmpty()) {Log.e("start","setContent()");
                setContent();
                StatusManager.getInstance().setUsermStatus(true);
                Log.e("UsermStatus:",String.valueOf(StatusManager.getInstance().getUsermStatus()));
            }

            super.onPostExecute(response);
        }

    }




    private void setContent(){
        SampleAdapter adapter = new SampleAdapter(getActivity());

        adapter.notifyDataSetChanged();

        try {
            if (!UserManager.getInstance().getUsers_mana().isEmpty()) {

                for (int i = 0; i < UserManager.getInstance().getUsers_mana().size(); i++) {

Log.e("adding to adapter:",UserManager.getInstance().getUsers_mana().get(i).firstName + " " + UserManager.getInstance().getUsers_mana().get(i).lastName + "" + UserManager.getInstance().getUsers_mana().get(i).id + "" + UserManager.getInstance().getUsers_mana().get(i).username + "group:" + UserManager.getInstance().getUsers_mana().get(i).group);
                    adapter.add(new SampleItem(
                            UserManager.getInstance().getUsers_mana().get(i).id
                            , UserManager.getInstance().getUsers_mana().get(i).firstName + " " + UserManager.getInstance().getUsers_mana().get(i).lastName
                            , UserManager.getInstance().getUsers_mana().get(i).username
                            , UserManager.getInstance().getUsers_mana().get(i).group
                            , R.drawable.users_test
                            , R.drawable.settings
                            , R.drawable.delete
                            , UserManager.getInstance().getUsers_mana().get(i).activated
                    ));

                }

                listView.setAdapter(adapter);Log.e("setting","ListView");
            }

        }catch (Exception e){
            Log.e("error setContent", e.getMessage().toString());
        }

    }


    /*
    private class PicturesTask extends AsyncTask<String, String ,String>{

        @Override
        protected String doInBackground(String... urls) {

            //String urldisplay = urls[0];
            Bitmap mIcon11 = null;
            try {
                for(int i = 0; i < urls.length; i++) {
                    if(UserManager.getInstance().getUsers_mana().get(i).photo != null) {

                        InputStream in = new java.net.URL(getString(R.string.jetfuel_url ) + UserManager.getInstance().getUsers_mana().get(i).username).openStream();
                        mIcon11 = BitmapFactory.decodeStream(in);

                        pictureses.add(new User_pictures(mIcon11, UserManager.getInstance().getUsers_mana().get(i).username, UserManager.getInstance().getUsers_mana().get(i).id));
                        UserManager.getInstance().setUserPictureses(pictureses);
                    }
                }
            } catch (Exception e) {
                Log.e("Error", e.getMessage());
                e.printStackTrace();
            }

            return null;
        }

        @Override
        protected void onPostExecute(String s) {
            if(!UserManager.getInstance().getUserPictureses().isEmpty()) {
                for (int i = 0; i < UserManager.getInstance().getUserPictureses().size(); i++) {
                    Log.v("pictures", UserManager.getInstance().getUserPictureses().get(i).picture + "");
                }
            }
            super.onPostExecute(s);
        }
    }
    */







    /**---------------------------------------------------------------------------------------------*/

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        inflater.inflate(R.menu.main, menu);

        //menu.removeItem(R.id.Station);
        super.onCreateOptionsMenu(menu, inflater);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        switch (item.getItemId()) {

            case R.id.Station:

                Fragment fragment = new Stations();
                FragmentManager fragmentManager = getFragmentManager();
                    fragmentManager.beginTransaction().replace(R.id.content_frame,     fragment).commit();

                return true;

            default:

                return super.onOptionsItemSelected(item);

        }

    }
    /**---------------------------------------------------------------------------------------------*/

}

xml 视图:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">




<LinearLayout
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/blue">







    <Button
        android:id="@+id/addUser_button"
        android:layout_width="fill_parent"
        android:layout_height="50dp"
        android:text="@string/add_user"

        android:background="@drawable/button_yellow_background"
        android:textStyle="bold"
        android:textSize="20sp"
        android:textColor="@color/blue"/>

    <android.support.v4.widget.SwipeRefreshLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        xmlns:android="http://schemas.android.com/apk/res/android"


    android:id="@+id/swipe">


    <ListView
        android:id="@+id/list"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="@color/blue"
        />

    </android.support.v4.widget.SwipeRefreshLayout>

</LinearLayout>



</RelativeLayout>

谢谢!

【问题讨论】:

    标签: android listview android-listview


    【解决方案1】:

    您的SampleAdapter.getView() 方法存在很大问题。

    当您向下滚动时,在屏幕顶部消失的View 被重新注入底部。这个重用的View 是您作为getView 参数获得的convertView

    正如您编写的代码一样,重用的视图会注入完全相同的数据(因为滚动时if (convertView == null) { 始终为假)。

    图片和文字没有更新。

    向下滚动时,顶部消失的元素只出现在底部,其他元素也是如此......

    你应该这样做:

    public View getView(final int position, View convertView, ViewGroup parent) {
    
        ViewHolder holder;
        if (convertView == null) {
            convertView = LayoutInflater.from(getContext()).inflate(R.layout.row_usermana, null);
    
            // The ViewHolder constructor should handle the mapping of its views
            holder = new ViewHolder(convertView);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }
        // Here you should only use holder as in:
        holder.userpicture.setImageDrawable(getResources().getDrawable(getItem(position).userPicture));
        ...
    }
    

    【讨论】:

      【解决方案2】:

      这种方法看起来很奇怪,而且可能值得怀疑。我在此示例代码的任何地方都没有看到 getUsers_mana() 定义,所以我不知道这是否是问题所在。一方面,您应该调用“UserManager.getInstance().getUsers_mana()”,然后每次调用一次“get(i)”,并将结果存储在变量中。

      private void setContent(){
          SampleAdapter adapter = new SampleAdapter(getActivity());
      
          adapter.notifyDataSetChanged();
      
          try {
              if (!UserManager.getInstance().getUsers_mana().isEmpty()) {
      
                  for (int i = 0; i < UserManager.getInstance().getUsers_mana().size(); i++) {
      
      Log.e("adding to adapter:",UserManager.getInstance().getUsers_mana().get(i).firstName + " " + UserManager.getInstance().getUsers_mana().get(i).lastName + "" + UserManager.getInstance().getUsers_mana().get(i).id + "" + UserManager.getInstance().getUsers_mana().get(i).username + "group:" + UserManager.getInstance().getUsers_mana().get(i).group);
                      adapter.add(new SampleItem(
                              UserManager.getInstance().getUsers_mana().get(i).id
                              , UserManager.getInstance().getUsers_mana().get(i).firstName + " " + UserManager.getInstance().getUsers_mana().get(i).lastName
                              , UserManager.getInstance().getUsers_mana().get(i).username
                              , UserManager.getInstance().getUsers_mana().get(i).group
                              , R.drawable.users_test
                              , R.drawable.settings
                              , R.drawable.delete
                              , UserManager.getInstance().getUsers_mana().get(i).activated
                      ));
      
                  }
      
                  listView.setAdapter(adapter);Log.e("setting","ListView");
              }
      
          }catch (Exception e){
              Log.e("error setContent", e.getMessage().toString());
          }
      
      }
      

      【讨论】:

      • 这段代码很丑是的。但是给定的代码是UserManagement 类,而不是UserManager 一个;)
      • 我不得不说我继承了在我之前做这个项目的人的代码,所以我仍然没有很好地处理它。 :( 它不返回 4,它返回预期的结果,适配器填充了适当的用户等,它只是没有显示在屏幕上。
      【解决方案3】:

      那是因为你什么都没做

      else {
      
                  convertView.getTag();
      
              }
      

      在这里查看

      Why we should re-assign values for a recycled convertView in getView()

      您必须使用第 5 roq、第 6 行等的数据将值重新分配给 convertView,否则它仍然包含旧数据

      【讨论】:

        【解决方案4】:

        去掉上面对holder的初始化,把这行代码放在getView函数的开头。

        ViewHolder holder = null;
        

        如果持有者为空,则需要重新初始化,如果不为空,则需要使用最新数据更新它。

        【讨论】:

          【解决方案5】:

          查看此示例可能对您有所帮助

          https://github.com/erikwt/PullToRefresh-ListView

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2021-11-07
            • 1970-01-01
            • 2023-03-15
            • 1970-01-01
            • 2017-05-09
            • 1970-01-01
            • 1970-01-01
            • 2013-11-18
            相关资源
            最近更新 更多