在我的应用程序中,我正在为具有多个视图的回收站视图实现自定义适配器。在适配器中,我列出了从主活动传入的对象列表,并在其中设置了视图和onClickListeners。对于我激发的一种意图,我正在编辑适配器中设置的内容。活动返回后-适配器不会更新。我不确定如何在活动完成后为适配器实现接口或onActivityForResult()方法以在RecyclerView中重新配置此视图。

我尝试实现一个接口,但是不确定如何在我在主要活动(片段)中声明适配器时准确地执行此操作,然后从那里添加对象列表。在适配器中,我根据添加的对象在其中设置视图。

这是我的主要片段类中的相关代码:
我正在向mObjects添加各种对象。

public class ProfileFragment extends Fragment{
    public final static String TAG = "ProfileFragment";  // tag for logging from this activity
    final ParseUser user = ParseUser.getCurrentUser();

    // For post feed:
    ArrayList<Object> mObjects;
    ArrayList<Post> mPosts;
    RecyclerView mLayout;
    MultiViewAdapter mMultiAdapter;

    // For stats view:
    HashMap<String, Integer> mCities;  // Contains the cities and number of times visited by user
    HashMap<String, Integer> mCountries;  // Contains the countries and number of times visited by user
    HashMap<String, Integer> mContinents;  // Contains the continents and number of times visited by user


    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.fragment_profile, container, false);
        setUpLogOutButton(v);

        // Populate stat maps and get posts
        mObjects = new ArrayList<>();
        mCities = new HashMap<>();
        mCountries = new HashMap<>();
        mContinents = new HashMap<>();
        mPosts = new ArrayList<>();

        // Get posts
        getPosts();
        mObjects.add(user);

        // For post feed view:
        mMultiAdapter = new MultiViewAdapter(getActivity(), mObjects);

        mLayout = v.findViewById(R.id.rvPosts);
        mLayout.setLayoutManager(new LinearLayoutManager(getContext()));
        mLayout.setAdapter(mMultiAdapter);

        return v;
    }
}


这是我的适配器中的相关代码:

public class MultiViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    Context mContext;
    ArrayList<Object> items;

    // Identifier for objects in items and which view to load:
    private final int USER_INFO = 0, POST = 1, STAT = 2;

    // The total number of cities, countries, and continents in the world:
    public final int totalNumCities = 4416;
    public final int totalNumCountries = 195;
    public final int totalNumContinents = 7;

    public MultiViewAdapter(Context context, ArrayList<Object> items) {
        this.items = items;
        this.mContext = context;
    }

    @Override
    public int getItemCount() {
        return items.size();
    }

    //Returns the view type of the item at position for the purposes of view recycling.
    @Override
    public int getItemViewType(int position) {
        if (items.get(position) instanceof Post) {
            return POST;
        } else if (items.get(position) instanceof ParseUser) {
            return USER_INFO;
        } else if(items.get(position) instanceof HashMap){
            return STAT;
        }
        return -1;
    }


    /**
     * This method creates different RecyclerView.ViewHolder objects based on the item view type.
     *
     * @param viewGroup ViewGroup container for the item
     * @param viewType  type of view to be inflated
     * @return viewHolder to be inflated
     */
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
        RecyclerView.ViewHolder viewHolder = null;
        LayoutInflater inflater = LayoutInflater.from(viewGroup.getContext());
        switch (viewType) {
            case POST:
                View v1 = inflater.inflate(R.layout.item_post_card, viewGroup, false);
                viewHolder = new PostViewHolder(v1);
                break;
            case USER_INFO:
                View v2 = inflater.inflate(R.layout.item_user_information, viewGroup, false);
                viewHolder = new UserInfoViewHolder(v2);
                break;
            case STAT:
                View v3 = inflater.inflate(R.layout.item_user_stats, viewGroup, false);
                viewHolder = new StatViewHolder(v3);
        }
        return viewHolder;
    }

    /**
     * This method internally calls onBindViewHolder(ViewHolder, int) to update the
     * RecyclerView.ViewHolder contents with the item at the given position
     * and also sets up some private fields to be used by RecyclerView.
     *
     * @param viewHolder The type of RecyclerView.ViewHolder to populate
     * @param position   Item position in the viewgroup.
     */
    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {
        switch (viewHolder.getItemViewType()) {
            case POST:
                PostViewHolder vh1 = (PostViewHolder) viewHolder;
                configurePostViewHolder(vh1, position);
                break;
            case USER_INFO:
                UserInfoViewHolder vh2 = (UserInfoViewHolder) viewHolder;
                configureUserInfoViewHolder(vh2, position);
                break;
            case STAT:
                StatViewHolder vh3 = (StatViewHolder) viewHolder;
                configureStatViewHolder(vh3, position);
                break;
        }
    }

    private void configureStatViewHolder(final StatViewHolder vh3, final int position){
        final HashMap<String, Integer> cities = (HashMap<String, Integer>) items.get(position);
        if(cities!= null){
            // For pie chart
            // Cities:
            // TODO: add pie chart for continents and countries and put this in seperate method
            List<PieEntry> pieEntries = new ArrayList<>();
            pieEntries.add(new PieEntry(cities.size(), "Visited Cities"));
            pieEntries.add(new PieEntry(totalNumCities-cities.size(), "Unvisited Cities"));
            PieDataSet pieDataSet = new PieDataSet(pieEntries, "City Stats");
            pieDataSet.setColors(R.color.colorPrimary, R.color.colorPrimaryDark);
            PieData pieData = new PieData(pieDataSet);
            vh3.getmPieChart().setData(pieData);
            vh3.getmPieChart().animateY(1000);
            vh3.getmPieChart().invalidate();
        }
    }

    private void configurePostViewHolder(final PostViewHolder vh1, final int position) {
        final Post post = (Post) items.get(position);
        if (post != null) {
            vh1.getRootView().setTag(post);
            String cityName = post.getCity();
            String countryName = post.getCountry();
            String continentName = post.getContinent();
            vh1.getTvName().setText(cityName + ", " + countryName + ", " + continentName);
            vh1.getTvName().setTextColor(Color.WHITE);
            vh1.getvPalette().setBackgroundColor(ContextCompat.getColor(mContext, R.color.grey));

            SimpleTarget<Bitmap> target = new SimpleTarget<Bitmap>() {
                @Override
                public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
                    vh1.getIvProfile().setImageBitmap(resource);
                    Palette p = Palette.from(resource).generate();
                    vh1.getvPalette().setBackgroundColor(ContextCompat.getColor(mContext, R.color.grey));
                }
            };

            vh1.getIvProfile().setTag(target);
            // TODO: Maybe don't crop image as it looks very small
            if(post.getImage()!=null) {
                Glide.with(mContext).asBitmap().load(post.getImage().getUrl()).centerCrop().into(target);
            } else {
                // TODO: fix default image loaded where no image present to be prettier
                Glide.with(mContext).asBitmap().load(R.drawable.ic_add_photo).centerCrop().into(target);
            }
            vh1.getIvProfile().setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Intent it = new Intent(mContext, EditPost.class);
                    Bundle bundle = new Bundle();
                    bundle.putSerializable(Post.class.getSimpleName(), post);
                    it.putExtras(bundle);
                    // Start activity for result to reconfigure user view after return
                    ((Activity) mContext).startActivityForResult(it, 2121);
                }
            });
        }
    }

    private void configureUserInfoViewHolder(UserInfoViewHolder vh2, final int position) {
        ParseUser user = (ParseUser) items.get(position);
        if (user != null) {
            if (user.getParseFile("profileImg") != null) {
                vh2.setmIvProfileImage(user.getParseFile("profileImg").getUrl(), mContext);
            } else {
Glide.with(mContext).load(R.drawable.ic_user).into(vh2.getmIvProfileImage());
            }
            vh2.getmTvEditProfile().setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Intent it = new Intent(mContext, UserSettings.class);
** SEE HERE FOR INTENT FIRED **
                    (mContext).startActivityForResult(it);
                }
            });
        }
    }



从那里开始我的UserSettings活动,用户可以在其中更改信息。

public class UserSettings extends AppCompatActivity {
    ImageView mIvProfileImage;
    TextView mTvEditPhoto;
    ImageView mIvBackArrow;
    ImageView mIvSave;
    EditText mEtUsername;
    EditText mEtNumber;
    EditText mEtEmail;
    public String photoFileName = "photo.jpg";
    public static final int REQUEST_CODE = 101;
    File mPhotoFile;
    ParseFile mParseFile;
    final ParseUser user = ParseUser.getCurrentUser();


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_user_settings);
      //  mIntentListener = getCallingActivity()

        // Set Views
        mIvProfileImage = findViewById(R.id.ivProfileImageMain);
        mTvEditPhoto = findViewById(R.id.tvEditPhoto);
        mIvBackArrow = findViewById(R.id.ivBack);
        mEtUsername = findViewById(R.id.etUsername);
        mEtNumber = findViewById(R.id.etNumber);
        mEtEmail = findViewById(R.id.etEmail);
        mIvSave = findViewById(R.id.ivSave);
        updateCurrentViews();

        // Set on click listener for photo
        mTvEditPhoto.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                AlertDialog.Builder builder = new AlertDialog.Builder(UserSettings.this);
                builder.setTitle("Upload or Take a Photo");
                builder.setPositiveButton("Upload", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        // Upload image
                        startActivityForResult(new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.INTERNAL_CONTENT_URI), Constants.GET_FROM_GALLERY);
                    }
                });
                builder.setNegativeButton("Take a Photo", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        // Take Photo
                        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                        PhotoHelper photoHelper = new PhotoHelper();
                        mPhotoFile = photoHelper.getPhotoFileUri(UserSettings.this, photoFileName);
                        Uri fileProvider = FileProvider.getUriForFile(UserSettings.this, "com.example.fileprovider", mPhotoFile);
                        intent.putExtra(MediaStore.EXTRA_OUTPUT, fileProvider);
                        if (intent.resolveActivity(UserSettings.this.getPackageManager()) != null) {
                            startActivityForResult(intent, Constants.CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
                        }
                    }
                });
                AlertDialog dialog = builder.create();
                dialog.show();
            }
        });

        // Go back to profile activity if user clicks back
        mIvBackArrow.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });

        mIvSave.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mParseFile != null) {
                    user.put("profileImg", mParseFile);
                }

                user.setEmail(mEtEmail.getText().toString());
                user.setUsername(mEtUsername.getText().toString());
                user.put("phone", mEtNumber.getText().toString());
                user.put("email", mEtEmail.getText().toString());
                setResult(RESULT_OK, new Intent());
                user.saveInBackground(new SaveCallback() {
                    @Override
                    public void done(ParseException e) {
                        updateCurrentViews();
                        finish();
                    }
                });
            }
        });
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, final Intent data) {
        if (requestCode == Constants.CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) {
            if (resultCode == this.RESULT_OK) {
                Bitmap takenImage = BitmapFactory.decodeFile(mPhotoFile.getAbsolutePath());
                mIvProfileImage.setImageBitmap(takenImage);
                PhotoHelper photoHelper = new PhotoHelper();
                File photoFile = photoHelper.getPhotoFileUri(this, photoFileName);
                mParseFile = new ParseFile(photoFile);
            } else {
                mParseFile = null;
                Toast.makeText(this, "Picture wasn't taken!", Toast.LENGTH_SHORT).show();
            }
        } else {
            if (resultCode == this.RESULT_OK) {
                Bitmap bitmap = null;
                Uri selectedImage = data.getData();
                try {
                    bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), selectedImage);
                } catch (Exception e) {
                }
                ByteArrayOutputStream stream = new ByteArrayOutputStream();
                bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
                byte[] image = stream.toByteArray();
                mParseFile = new ParseFile("profpic.jpg", image);
                final Bitmap finalBitmap = bitmap;
                Glide.with(this).load(finalBitmap).into(mIvProfileImage);
            } else {
                mParseFile = null;
            }
        }
    }

    public void updateCurrentViews() {
        // For profile image:
        mIvProfileImage = findViewById(R.id.ivProfileImageMain);
        if (user.getParseFile("profileImg") != null) {
            Glide.with(this).load(user.getParseFile("profileImg").getUrl()).into(mIvProfileImage);
        } else {
            Glide.with(this).load(R.drawable.ic_user).into(mIvProfileImage);
        }

        // EditText:
        mEtUsername.setText(user.getUsername());
        mEtNumber.setText(String.format("%s", user.get("phone")));
        mEtEmail.setText(String.format("%s", user.get("email")));
    }
}



问题是当UserSettingsActivity完成更新的信息时,该信息未反映在适配器中,并且显示了旧信息。

编辑回应以回复评论
这是我的主要活动:

public class HomeActivity extends AppCompatActivity {
    final FragmentManager fragmentManager = getSupportFragmentManager();

    final Fragment fragment1 = new MapFragment();
    final Fragment fragment2 = new DiscoverFragment();
    final Fragment fragment3 = new ProfileFragment();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home);
        BottomNavigationView navView = findViewById(R.id.nav_view);
        navView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
                Fragment fragment;
                switch (menuItem.getItemId()) {
                    case R.id.navigation_home:
                        fragment = fragment1;
                        break;
                    case R.id.navigation_dashboard:
                        fragment = fragment2;
                        break;
                    case R.id.navigation_notifications:
                    default:
                        fragment = fragment3;
                        break;
                }
                fragmentManager.beginTransaction().replace(R.id.flContainer, fragment).commit();
                return true;
            }
        });
        navView.setSelectedItemId(R.id.navigation_home);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
    }
}


在我的ProfileFragment中,我添加了:

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if(resultCode == 2121){
            // the user information is at item 0
            mMultiAdapter.notifyItemChanged(0);
        }
    }


在适配器中,我从以下代码开始活动:

((Activity) mContext).startActivityForResult(it, 2121);

最佳答案

您需要在ProfileFragment中具有onActivityResult()函数,因为它将在UserSettings活动完成时被调用。从那里您可以得到意图,并获得更改的数据。您的ProfileFragment具有适配器的实例,因此您可以在更新对象后调用notifyItemChanged函数。

10-05 21:15
查看更多