如何将ParseObjects与RecyclerView一起使用?

时间:2018-01-22 13:36:35

标签: java android android-recyclerview android-adapter bitnami

我正在尝试从我的解析服务器中提取数据,并在CardView的RecyclerView中显示图像和文本。我遇到了一些问题,其中一些可能没有得到适当的纠正,所以请在我目前的两个问题之外随时纠正您在下面找到的任何新手代码。最后我的两个问题是。

  1. 最初不显示数据。我在ViewPager中有3个选项卡,我必须滑动两次才能显示它。如果我在标签1上显示数据,则直到我滑动到标签3并返回标签1,数据才会显示,反之亦然。由于没有标签4,标签2永远不会显示。

  2. 我目前面临的第二个问题是有时数据不匹配。它将使一行中的图片与另一实体的描述相匹配。

  3. 以下是我的MusicFragment.java

    public class MusicFragment extends Fragment {
    
        private ArrayList<String> titles = new ArrayList<>();
        private ArrayList<Bitmap> bitmaps = new ArrayList<>();
        private ArrayList<String> descriptions = new ArrayList<>();
    
        private boolean notComplete = true;
    
        public MusicFragment() {
            // Required empty public constructor
        }
    
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            //  Inflate the layout for this fragment
            RecyclerView musicRecycler = (RecyclerView)inflater.inflate(
                                R.layout.fragment_music, container, false);
    
            if (notComplete) {
                //  Get the MusicFragImages class as a reference.
                ParseQuery<ParseObject> query = new ParseQuery<>("MusicFragImages");
    
                query.findInBackground(new FindCallback<ParseObject>() {
                    @Override
                    public void done(List<ParseObject> objects, ParseException e) {
    
                        if (e == null) {
                            for (ParseObject object : objects) {
                                String description = (String) object.get("description");
                                ParseFile file = (ParseFile) object.get("image");
                                String title = (String) object.get("title");
    
                                titles.add(title);
                                descriptions.add(description);
    
                                file.getDataInBackground(new GetDataCallback() {
                                    @Override
                                    public void done(byte[] data, ParseException e) {
                                        if (e == null && data != null) {
                                            Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
                                            bitmaps.add(bitmap);
                                        }
                                    }
                                });
                            }
                        } else {
                            Toast.makeText(getContext(), e.getMessage(), Toast.LENGTH_SHORT).show();
                        }
                    }
    
                });
                notComplete = false;
            }
            //  Create captioned images and registers it to the adapter.
            CaptionedImagesAdapter adapter = new CaptionedImagesAdapter(titles, bitmaps, descriptions);
            musicRecycler.setAdapter(adapter);
    
            //  Set up the layout.
            GridLayoutManager layoutManager = new GridLayoutManager(getActivity(), 1);
            musicRecycler.setLayoutManager(layoutManager);
    
            adapter.setListener(new CaptionedImagesAdapter.Listener() {
               public void onClick(int position) {
                   Intent intent;
                   switch (position) {
                       case 0:
                           intent = new Intent(getActivity(), AudioActivity.class);
                           getActivity().startActivity(intent);
                           break;
                       case 1:
                           intent = new Intent(getActivity(), VideoActivity.class);
                           getActivity().startActivity(intent);
                           break;
                   }
               }
            });
    
            return musicRecycler;
        }
    }
    

    此外,这是我的CaptionedImagesAdapter

    class CaptionedImagesAdapter extends
        RecyclerView.Adapter<CaptionedImagesAdapter.ViewHolder> {
    
        private final ArrayList<String> captions;
        private final ArrayList<Bitmap> bitmaps;
        private final ArrayList<String> descriptions;
    
        private Listener listener;
    
        interface Listener {
            void onClick(int position);
        }
    
        public static class ViewHolder extends RecyclerView.ViewHolder {
    
            private final CardView cardView;
    
            public ViewHolder(CardView v) {
                super(v);
                cardView = v;
            }
        }
    
        public CaptionedImagesAdapter(ArrayList<String> captions, ArrayList<Bitmap> bitmaps, ArrayList<String> descriptions) {
            this.captions = captions;
            this.bitmaps = bitmaps;
            this.descriptions = descriptions;
        }
    
        @Override
        public int getItemCount() {
            return captions.size();
        }
    
        public void setListener(Listener listener) {
            this.listener = listener;
        }
        @Override
        public CaptionedImagesAdapter.ViewHolder onCreateViewHolder(
                ViewGroup parent, int viewType) {
            CardView cv = (CardView) LayoutInflater.from(parent.getContext()).inflate(R.layout.card_selection_2, parent, false);
            return new ViewHolder(cv);
        }
        @Override
        public void onBindViewHolder(ViewHolder holder, int position) {
            final int index = position;
    
            //  Creates a CardView
            CardView cardView = holder.cardView;
    
            ImageView imageView = cardView.findViewById(R.id.type_image);
            imageView.setImageBitmap(bitmaps.get(index));
    
            imageView.setContentDescription(descriptions.get(index));
    
            //  Populate the caption.
            TextView textView = cardView.findViewById(R.id.type_text);
            textView.setText(captions.get(index));
            cardView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v){
                    if (listener != null)
                        listener.onClick(index);
                }
            });
        }
    }
    

    FOR REFERENCE ......如果需要,MainActivity.java位于

    之下
        public class MainActivity extends AppCompatActivity {
    
    //  Variables for the audio player.
    public static MediaPlayer mediaPlayer;
    public static int albumId;
    public static int currentSong = -1;
    public static boolean isPlaying = false;
    private static int[] songs;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    
        Toolbar toolbar = (Toolbar)findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
    
        //  Attach the SectionsPageAdapter to the ViewPager
        SectionsPageAdapter pagerAdapter = new SectionsPageAdapter(getSupportFragmentManager());
        ViewPager pager = (ViewPager) findViewById(R.id.pager);
        pager.setAdapter(pagerAdapter);
        int currentTab = 0;
        pager.setCurrentItem(currentTab);
    
        //  Attach the ViewPager to the TabLayout
        TabLayout tabLayout = (TabLayout)findViewById(R.id.tabs);
        tabLayout.setupWithViewPager(pager);
    
        //  Starts the player.
        player();
    }
    public boolean onCreateOptionsMenu(Menu menu) {
        //  Inflate the menu; this adds items to the app bar.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return super.onCreateOptionsMenu(menu);
    }
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        Intent intent;
        switch (item.getItemId()) {
            case R.id.action_contact:
                intent = new Intent(MainActivity.this, ContactActivity.class);
                startActivity(intent);
                return true;
            case R.id.action_cart:
                intent = new Intent(this, CartActivity.class);
                startActivity(intent);
                return true;
            case R.id.action_member:
                intent = new Intent(this, ProfileActivity.class);
                startActivity(intent);
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }
    private class SectionsPageAdapter extends FragmentPagerAdapter {
    
        public SectionsPageAdapter(FragmentManager fm) {
            super(fm);
        }
        @Override
        public int getCount() {
            return 3;
        }
        @Override
        public Fragment getItem(int position) {
            switch (position) {
                case 0:
                    return new MusicFragment();
                case 1:
                    return new ArtFragment();
                case 2:
                    return new FashionFragment();
            }
            return null;
        }
        @Override
        public CharSequence getPageTitle(int position) {
            switch (position) {
                case 0:
                    return getResources().getText(R.string.title_music);
                case 1:
                    return getResources().getText(R.string.title_art);
                case 2:
                    return getResources().getText(R.string.title_fashion);
            }
            return null;
        }
    }
    private void player() {
    
        /*Create a background thread that will automatically advance to
                    * the next song, as long as there is a next song.*/
    
        //  Get the songs.
        songs = AudioData.audio[albumId].getSongs();
    
        final Handler handler = new Handler();
        handler.post(new Runnable() {
            @Override
            public void run() {
                if (isPlaying) {
                    if (!(mediaPlayer.isPlaying()) && currentSong < songs.length - 1) {
                        mediaPlayer.stop();
                        mediaPlayer.reset();
                        currentSong++;
                        mediaPlayer = MediaPlayer.create(MainActivity.this, songs[currentSong]);
                        mediaPlayer.start();
                        isPlaying = true;
                    }
                    //Set the flag to false at the end of the album.
                    if (currentSong == songs.length) {
                        isPlaying = false;
                    }
                }
                handler.postDelayed(this, 1000);
            }
        });
    }
    
    @Override
    public void onBackPressed() {
        super.onBackPressed();
        finishAffinity();
    }
    

    }

    再次感谢Harikumar纠正第一期。我最后用下面的代码纠正了第二个问题。它在增强循环中。

        for (ParseObject object : objects) {
                            String description = (String) object.get("description");
                            ParseFile file = (ParseFile) object.get("image");
                            String title = (String) object.get("title");
                            Bitmap bitmap;
    
    
                            titles.add(title);
                            descriptions.add(description);
    
                            byte[] data;
                            try {
                                data = file.getData();
                                bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
                                bitmaps.add(bitmap);
                                adapter.notifyDataSetChanged(); //notify your adapter that data has changed
                            } catch (ParseException pe) {
                                Toast.makeText(getContext(), pe.getMessage(), Toast.LENGTH_SHORT).show();
                            }
                        }
    

1 个答案:

答案 0 :(得分:0)

如果您通知适配器CaptionedImagesAdapter,数据将会更新。尝试将代码修改为:

public class MusicFragment extends Fragment {

    private ArrayList<String> titles = new ArrayList<>();
    private ArrayList<Bitmap> bitmaps = new ArrayList<>();
    private ArrayList<String> descriptions = new ArrayList<>();
    private CaptionedImagesAdapter adapter;


    private boolean notComplete = true;

    public MusicFragment() {
        // Required empty public constructor
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        //  Inflate the layout for this fragment
        RecyclerView musicRecycler = (RecyclerView)inflater.inflate(
                            R.layout.fragment_music, container, false);


        GridLayoutManager layoutManager = new GridLayoutManager(getActivity(), 1);
        musicRecycler.setLayoutManager(layoutManager);

        adapter = new CaptionedImagesAdapter(titles, bitmaps, descriptions);

        musicRecycler.setAdapter(adapter);

        if (notComplete) {
            //  Get the MusicFragImages class as a reference.
            ParseQuery<ParseObject> query = new ParseQuery<>("MusicFragImages");

            query.findInBackground(new FindCallback<ParseObject>() {
                @Override
                public void done(List<ParseObject> objects, ParseException e) {

                    if (e == null) {
                        for (ParseObject object : objects) {
                            String description = (String) object.get("description");
                            ParseFile file = (ParseFile) object.get("image");
                            String title = (String) object.get("title");

                            titles.add(title);
                            descriptions.add(description);

                            file.getDataInBackground(new GetDataCallback() {
                                @Override
                                public void done(byte[] data, ParseException e) {
                                    if (e == null && data != null) {
                                        Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
                                        bitmaps.add(bitmap);
                                        adapter.notifyDataSetChanged(); //notify your adapter that data has changed
                                    }
                                }
                            });
                        }
                    } else {
                        Toast.makeText(getContext(), e.getMessage(), Toast.LENGTH_SHORT).show();
                    }
                }

            });
            notComplete = false;
        }


        adapter.setListener(new CaptionedImagesAdapter.Listener() {
           public void onClick(int position) {
               Intent intent;
               switch (position) {
                   case 0:
                       intent = new Intent(getActivity(), AudioActivity.class);
                       getActivity().startActivity(intent);
                       break;
                   case 1:
                       intent = new Intent(getActivity(), VideoActivity.class);
                       getActivity().startActivity(intent);
                       break;
               }
           }
        });

        return musicRecycler;
    }
}

以下是针对您的第二个解决方案的一个小优化:在for循环之后仅更新notifyDataSetChanged()一次(将其放在for循环之外)。这在性能方面更好。