android - 如何操作 ListView 项目内的 View ?

标签 android listview android-listview android-view

我有一个 ListView,其中有几行包含两个按钮和一个 ProgressBar (Visibility:GONE)

我的目的是在单击按钮时显示 ProgressBar,并在完成一组特定的后台操作后完全删除该行。
这里的问题是,从创建 ListViewArrayList 中删除项目并调用 notifyDataSetChanged 后,该行已成功删除,但是 ProgressBar 保持可见。

它不应该与其父 View 一起删除吗?

检查以下记录以查看实际问题。

enter image description here

这是我整个 fragment 的来源:

public class FriendRequestFragment extends Fragment implements SwipeRefreshLayout.OnRefreshListener {


    private static final String TAG = "FriendRequestFragment";
    ArrayList<FriendRequest> friendRequests;

    @InjectView(R.id.friendRequestList)
    ListView mListView;
    @InjectView(R.id.noRequestsText)
    TextView noRequestsText;
    @InjectView(R.id.swipe)
    SwipeRefreshLayout swipeRefreshLayout;

//    NotificationHandler nh;
    /**
     * The Adapter which will be used to populate the ListView/GridView with
     * Views.
     */
    private FriendRequestAdapter mAdapter;
    private Context c;
    private boolean isProcessing = false;

    /**
     * Mandatory empty constructor for the fragment manager to instantiate the
     * fragment (e.g. upon screen orientation changes).
     */
    public FriendRequestFragment() {
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Util.trackFragment(this);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_friendrequest_list, container, false);
        ButterKnife.inject(this, view);
        c = getActivity();
        friendRequests = new ArrayList<>();
        swipeRefreshLayout.setOnRefreshListener(this);
        mAdapter = new FriendRequestAdapter(getActivity(), friendRequests);

        mListView.setAdapter(mAdapter);

        mListView.setOnScrollListener(new AbsListView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(AbsListView view, int scrollState) {

            }

            @Override
            public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
                int topRowVerticalPosition =
                        (view == null || view.getChildCount() == 0) ?
                        0 : view.getChildAt(0).getTop();
                swipeRefreshLayout.setEnabled(firstVisibleItem == 0 && topRowVerticalPosition >= 0);
                Log.d(TAG, "SwipeRefresh: " + String.valueOf(firstVisibleItem == 0 && topRowVerticalPosition >= 0));
            }
        });


        loadRequests();
        return view;
    }

    private void loadRequests() {
//        nh = new NotificationHandler(getActivity());
        swipeRefreshLayout.setRefreshing(true);
        Log.d(TAG, "loading requests init");
        HashMap<String, Integer> params = new HashMap<>();
        params.put("profile_id", Util.getCurrentProfileID(c));
        final String uniqueID = Util.getCurrentProfileID(c) + String.valueOf(System.currentTimeMillis() / 1000 / 1200);
        new ApiRequest(Util.URL_GET_FRIEND_REQUESTS, params, new AjaxCallback<String>() {
            @Override
            public void callback(String url, String result, AjaxStatus status) {
                super.callback(url, result, status);
                ApiResponse apiResponse = new ApiResponse(url, result, uniqueID);
                Log.d(TAG, "Friend Requests Response: " + result);
                if (apiResponse.isSuccessful()) {
                    JSONArray jsonArray = apiResponse.getDataJSONArray();
                    try {
                        for (int i = 0; i < jsonArray.length(); i++) {
                            friendRequests.add(new FriendRequest(jsonArray.getJSONObject(i)));
                        }
                        mAdapter.notifyDataSetChanged();
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                    mListView.setVisibility(View.VISIBLE);
                } else if (apiResponse.getErrorMessage().equals("request_not_found")) {
                    noRequestsText.setVisibility(View.VISIBLE);
                }
                swipeRefreshLayout.setRefreshing(true);
            }

        }).setUniqueID(uniqueID).execute();
    }

    @Override
    public void onRefresh() {
        loadRequests();
    }

    private void acceptRequest(final int position, final View rootView) {
        if (isProcessing) {
            CustomToast.makeToast(getActivity(), CustomToast.TYPE_ALERT, getString(R.string.please_wait), CustomToast.LENGTH_SHORT);
            return;
        }
        rootView.findViewById(R.id.loading).setVisibility(View.VISIBLE);
        rootView.findViewById(R.id.acceptBtn).setVisibility(View.GONE);
        rootView.findViewById(R.id.denyBtn).setVisibility(View.GONE);
        isProcessing = true;
        Log.d("FriendRequest", "accepting:" + position);
        FriendRequest request = friendRequests.get(position);
        HashMap<String, Integer> params = new HashMap<>();
        params.put("request_id", request.getRequestID());
        params.put("profile_id", ProfilesSingleton.getInstance().getCurrentProfile().getProfileID());
        new ApiRequest(Util.URL_ACCEPT_REQUEST, params, new AjaxCallback<String>() {
            @Override
            public void callback(String url, String object, AjaxStatus status) {
                super.callback(url, object, status);
                ApiResponse apiResponse = new ApiResponse(object);
                if (apiResponse.isSuccessful()) {
                    friendRequests.remove(position);
                    CustomToast.makeToast(getActivity(), CustomToast.TYPE_DEFAULT,
                            getString(R.string.you_are_now_friends_with) + " " + friendRequests.get(position).getFullName(),
                            CustomToast.LENGTH_SHORT);
                    mAdapter.notifyDataSetChanged();
                }else {
                    rootView.findViewById(R.id.loading).setVisibility(View.GONE);
                    rootView.findViewById(R.id.acceptBtn).setVisibility(View.VISIBLE);
                    rootView.findViewById(R.id.denyBtn).setVisibility(View.VISIBLE);
                }
                isProcessing = false;
            }
        }).execute();
    }

    private void denyRequest(final int position, final View rootView) {
        if (isProcessing) {
            CustomToast.makeToast(getActivity(), CustomToast.TYPE_ALERT, getString(R.string.please_wait), CustomToast.LENGTH_SHORT);
            return;
        }
        rootView.findViewById(R.id.loading).setVisibility(View.VISIBLE);
        rootView.findViewById(R.id.acceptBtn).setVisibility(View.GONE);
        rootView.findViewById(R.id.denyBtn).setVisibility(View.GONE);
        Log.d("FriendRequest", "denying:" + position);
        FriendRequest request = friendRequests.get(position);
        HashMap<String, Integer> params = new HashMap<>();
        params.put("request_id", request.getRequestID());
        params.put("profile_id", ProfilesSingleton.getInstance().getCurrentProfile().getProfileID());
        new ApiRequest(Util.URL_DENY_REQUEST, params, new AjaxCallback<String>() {
            @Override
            public void callback(String url, String object, AjaxStatus status) {
                super.callback(url, object, status);
                ApiResponse apiResponse = new ApiResponse(object);
                if (apiResponse.isSuccessful()) {
                    friendRequests.remove(position);
                    mAdapter.notifyDataSetChanged();
                }else {
                    rootView.findViewById(R.id.loading).setVisibility(View.GONE);
                    rootView.findViewById(R.id.acceptBtn).setVisibility(View.VISIBLE);
                    rootView.findViewById(R.id.denyBtn).setVisibility(View.VISIBLE);
                }
            }
        }).execute();
    }

    public class FriendRequestAdapter extends ArrayAdapter<FriendRequest> {

        public FriendRequestAdapter(Context context, ArrayList<FriendRequest> objects) {
            super(context, 0, objects);
        }

        @Override
        public View getView(final int position, View convertView, ViewGroup parent) {
            View rootView = convertView;
            final ViewHolder holder;
            final FriendRequest friendRequest = getItem(position);
            if (rootView == null) {
                LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                rootView = inflater.inflate(R.layout.friend_request_item, parent, false);
                holder = new ViewHolder();
                holder.profilePhoto = (RoundedImageView) rootView.findViewById(R.id.profilePhoto);
                holder.fullName = (TextView) rootView.findViewById(R.id.fullName);
                holder.acceptBtn = (ImageView) rootView.findViewById(R.id.acceptBtn);
                holder.denyBtn = (ImageView) rootView.findViewById(R.id.denyBtn);
                holder.loading = (ProgressBar) rootView.findViewById(R.id.loading);
                rootView.setTag(holder);
            } else {
                holder = (ViewHolder) rootView.getTag();
            }

            holder.fullName.setText(friendRequest.getFullName());
            if (friendRequest.getFullPhotoPath().equals("")) {
                ImageUtil.replaceWithInitialsView(getContext(), holder.profilePhoto, friendRequest.getInitials());
            } else {
                Util.aQuery.id(holder.profilePhoto).image(friendRequest.getFullPhotoPath(), false, true, 50, R.drawable.avatar_profile, null, AQuery.FADE_IN);
            }

            final View finalRootView = rootView;
            holder.acceptBtn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    acceptRequest(position, finalRootView);
                }
            });
            holder.denyBtn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    denyRequest(position, finalRootView);
                }
            });
            return rootView;
        }

        public class ViewHolder {
            RoundedImageView profilePhoto;
            TextView fullName;
            ImageView acceptBtn, denyBtn;
            ProgressBar loading;
        }
    }
}

最佳答案

在保存进度条当前状态的 FriendRequest 类中添加一个字段。基于它设置进度条的可见性。

同一 View 行已发送到另一行。在您的 getView 方法中,您必须始终根据其状态设置进度条可见性。

代码示例:

        final View finalRootView = rootView;

        if (friendRequest.acceptingRequestInProgress())
             holder.loading.setVisibility(View.Visibile);
        else
             holder.loading.setVisibility(View.Gone);

        holder.acceptBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                friendRequest.setAcceptingInProgress(true);
                acceptRequest(position, finalRootView);
            }
        });
        holder.denyBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                denyRequest(position, finalRootView);
            }
        });

另外修改的地方:

if (apiResponse.isSuccessful()) {
    friendRequest.setAcceptingInProgress(false);
    friendRequests.remove(position);
    mAdapter.notifyDataSetChanged();
}

Note: this is also handles the case when the user scrolls the list view and the row view in progress is no longer visible. this will hands the view to another row. But since we check the row state the progress bar will be stopped. and when user scrolls back to the row view in progress and hands it a reusable view the progress bar will be visible again if accepting is still in progress.

关于android - 如何操作 ListView 项目内的 View ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30166872/

相关文章:

android - Google Play 服务和 Firebase 冲突

android - 是否可以使用私有(private) Intent 而不是全局 Intent ?

Android:尝试用英语以外的另一种语言阅读单词

java - listview.setAdapter(null) 似乎不起作用

android - 嵌套 ListView 仅首先运行 getView()

android - RecyclerView + Glide 显示结果一团糟

android - android 设备中的 egnos 定位

android - 如何在Android中获取Listview项选择的计数

java - 从 ListView 中获取选定的对象

android - 在其适配器上使用 changeCursor() 后,ListView 不会刷新