如何在RecyclerView中使用ParseObjects? [英] How to use ParseObjects with a RecyclerView?

查看:81
本文介绍了如何在RecyclerView中使用ParseObjects?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am attempting to pull data from my parse server and display an image and text within a RecyclerView of CardViews. I have encountered a few issues, some of which may not have been corrected appropriately, so please feel free to correct any novice code you find below outside of my two current issues. Finally my two issues are.

  1. 最初不显示数据.我在ViewPager中有3个标签,并且必须滑过两次才能显示.如果我位于选项卡1上,则只有在我滑动到选项卡3并返回到选项卡1时,数据才会出现,反之亦然.因为没有选项卡4,所以选项卡2永远不会显示.

  1. The data does not display initially. I have 3 tabs in a ViewPager and I have to swipe over twice in order for it to display. If I'm on tab 1 the data doesn't appear until I swipe to tab 3 and return to tab 1, and vice versa. Because there isn't a tab 4, tab 2 never displays.

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

The second issue I am currently faced with is that at times the data will not match up. It will have the picture from one row matched with the description from another entity.

下面是我的MusicFragment.java

Below is my 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

Additionally, here is my 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);
            }
        });
    }
}

供参考...如果需要,MainActivity.java在下面

FOR REFERENCE...... if needed MainActivity.java is below

    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循环之内.

Thanks again to Harikumar for correcting the first issue. I ended up correcting the second issue with the code below. It was within the enhance for loop.

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

推荐答案

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

Data will be updated if you notify your adapter CaptionedImagesAdapter. Try modifying the code to:

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循环外).就性能而言,这更好.

Here is a small optimization for your 2nd solution: update notifyDataSetChanged() only once after the for loop (put it just outside the for loop). This is better in terms of performance.

这篇关于如何在RecyclerView中使用ParseObjects?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆