动态cardviews与firebase结合使用

时间:2017-10-14 17:16:39

标签: android firebase firebase-realtime-database firebase-storage android-cardview

我有 SparkConf configuration = new SparkConf() .setAppName("Your Application Name") .setMaster("local"); val sc = new SparkContext(conf); 的列表。每个CardViews(代表挑战)都有CardView来显示""解决方案"的垂直可扫描列表。

"解决方案列表中的数据和图像"来自ViewPager数据库。 我遇到的问题是您打开的第一个CardView (当您点击它时,它会展开并显示解决方案)正确显示所有解决方案。当你点击第二个时,它会扩展,但没有显示数据,我认为它是这样的,因为我必须使用" final"布局Firebase

enter image description here

以下是自定义final FrameLayout v0 = (FrameLayout) inflater.inflate(R.layout.solutions, null);适配器的重要部分的片段。

RecyclerView

这是challenge_row.xml:

public class ChallengesAdapter extends 
RecyclerView.Adapter<ChallengesAdapter.RecyclerItemViewHolder> {
private ArrayList<ChallengesData> myChallengesList;
int mLastPosition = 0;

//Firebase
String mUID = FirebaseAuth.getInstance().getCurrentUser().getUid();
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
DatabaseReference challengeSolutionsRef = rootRef.child("challenges");

FirebaseStorage storage = FirebaseStorage.getInstance();
StorageReference storageRef = storage.getReferenceFromUrl("firebase-url");

public ChallengesAdapter(ArrayList<ChallengesData> myChallengesList) {
    this.myChallengesList = myChallengesList;
}
public RecyclerItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.challenges_row, parent, false);
    RecyclerItemViewHolder holder = new RecyclerItemViewHolder(view);
    return holder;
}
@Override
public void onBindViewHolder(RecyclerItemViewHolder holder, final int position) {
    holder.etTitleTextView.setText(myChallengesList.get(position).getTitle());
    holder.etDescriptionTextView.setText(myChallengesList.get(position).getDescription());
    mLastPosition =position;
}
@Override
public int getItemCount() {
    return(null != myChallengesList ? myChallengesList.size():0);
}
public void notifyData(ArrayList<ChallengesData> myList) {
    this.myChallengesList = myList;
    notifyDataSetChanged();
}
public class RecyclerItemViewHolder extends RecyclerView.ViewHolder {
    private final TextView etTitleTextView;
    private final TextView etDescriptionTextView;
    //private final TextView etContent;
    private final ChallengesPagerAdapter myChallengesPagerAdapter;
    private final ViewPager myViewPager;
    private final FrameLayout myFrameLayout;
    private LinearLayout mainLayout;

    public RecyclerItemViewHolder(final View parent) {
        super(parent);
        etTitleTextView = (TextView) parent.findViewById(R.id.txtTitle);
        etDescriptionTextView = (TextView) parent.findViewById(R.id.txtDescription);
        myViewPager = (ViewPager) parent.findViewById(R.id.view_pager);
        myChallengesPagerAdapter = new ChallengesPagerAdapter();
        myViewPager.setAdapter(myChallengesPagerAdapter);
        myFrameLayout = (FrameLayout) parent.findViewById(R.id.framelayout_view_pager);
        mainLayout = (LinearLayout) parent.findViewById(R.id.mainLayout);

        mainLayout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                challengeSolutionsRef = challengeSolutionsRef.child(myChallengesList.get(getAdapterPosition()).getChallengeKey()).child("solutions");
                challengeSolutionsRef.addChildEventListener(new ChildEventListener() {
                    @Override
                    public void onChildAdded(DataSnapshot dataSnapshot, String previousChildName) {
                        final LayoutInflater inflater = (LayoutInflater)parent.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);

                        DatabaseReference solutionsRef = rootRef.child("solutions").child(dataSnapshot.getKey());
                        solutionsRef.addValueEventListener(new ValueEventListener() {
                            @Override
                            public void onDataChange(DataSnapshot dataSnapshot) {
                                final FrameLayout v0 = (FrameLayout) inflater.inflate(R.layout.solutions, null);
                                TextView TVSolutionID = (TextView)v0.findViewById(R.id.txtSolutionID);
                                TextView TVUserID = (TextView)v0.findViewById(R.id.txtUserID);
                                TVSolutionID.setText(dataSnapshot.getKey());
                                String UserID = dataSnapshot.child("userId").getValue(String.class);
                                TVUserID.setText(UserID);

                                myChallengesPagerAdapter.notifyDataSetChanged();

                                //get file from cloud
                                storageRef.child("solutions/").child(dataSnapshot.child("images").getValue(String.class) + ".jpg").getBytes(Long.MAX_VALUE).addOnSuccessListener(new OnSuccessListener<byte[]>() {
                                    @Override
                                    public void onSuccess(byte[] bytes) {
                                        // Use the bytes to display the image
                                        Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
                                        ImageView IVSolution = (ImageView)v0.findViewById(R.id.ivSolutionImage);
                                        IVSolution.setImageBitmap(bitmap);
                                        myChallengesPagerAdapter.notifyDataSetChanged();
                                    }
                                }).addOnFailureListener(new OnFailureListener() {
                                    @Override
                                    public void onFailure(@NonNull Exception exception) {
                                        ImageView IVSolution = (ImageView)v0.findViewById(R.id.ivSolutionImage);
                                        IVSolution.setImageResource(R.mipmap.ic_challenger_black);
                                        myChallengesPagerAdapter.notifyDataSetChanged();
                                    }
                                });
                                myChallengesPagerAdapter.addView(v0);
                                myChallengesPagerAdapter.notifyDataSetChanged();
                            }
                            @Override
                            public void onCancelled(DatabaseError databaseError) {
                                Log.d("Test","The read failed: " + databaseError.getCode());
                            }

                        });
                    }

                        ....

                });

                ....
            }
        });
    }
}
}

这是solutions.xml:

<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_margin="8dp"
android:id="@+id/card_view"
android:layout_height="wrap_content">
<LinearLayout
    android:orientation="vertical"
    android:id="@+id/mainLayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <TextView
        android:id="@+id/txtTitle"
        android:padding="12dp"
        android:layout_width="match_parent"
        android:textColor="@android:color/black"
        android:layout_height="wrap_content" />
    <TextView
        android:id="@+id/txtDescription"
        android:padding="12dp"
        android:layout_width="match_parent"
        android:textColor="@android:color/black"
        android:layout_height="wrap_content" />
    <FrameLayout
        android:id="@+id/framelayout_view_pager"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:visibility="gone">

        <android.support.v4.view.ViewPager
            android:id="@+id/view_pager"
            android:layout_width="match_parent"
            android:layout_height="300dp">
        </android.support.v4.view.ViewPager>
        <ImageButton
            android:id="@+id/arrow_back"
            android:layout_width="48dp"
            android:layout_height="48dp"
            android:layout_gravity="center_vertical|left"
            android:src="@drawable/ic_arrow_back" />

        <ImageButton
            android:id="@+id/arrow_forward"
            android:layout_width="48dp"
            android:layout_height="48dp"
            android:layout_gravity="center_vertical|right"
            android:src="@drawable/ic_arrow_forward" />
</FrameLayout>
</LinearLayout>

根据马科斯的建议进行编辑:(结果仍然相同)

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent" android:layout_height="wrap_content">
    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <TextView
            android:id="@+id/txtSolutionID"
            android:padding="12dp"
            android:layout_width="match_parent"
            android:textColor="@android:color/black"
            android:layout_height="wrap_content"/>
        <TextView
            android:id="@+id/txtUserID"
            android:padding="12dp"
            android:layout_width="match_parent"
            android:textColor="@android:color/black"
            android:layout_height="wrap_content"/>
        <ImageView
            android:id="@+id/ivSolutionImage"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    </LinearLayout>
</FrameLayout>

2 个答案:

答案 0 :(得分:0)

现在您已按照解决方案进行操作,您需要解决此问题:

 holder.v0 = (FrameLayout) holder.myInflater.inflate(R.layout.solutions, null);

此语句创建的视图未附加到ViewHolder,结果将为空。

在ViewHolder构造函数中获取viewholder中的viewpager(不是主视图)的引用,并为其分配一个solutionsAdapter。

SolutionsAdapter将保存一个对象列表,您将在我指出的那一行的位置进行修改。

解决方案适配器将在创建视图上提供holder.myInflater.inflate(R.layout.solutions,null,false)的实例,并在onBindViewHolder中设置值。

要点:

您的屏幕上有一个带有一个适配器的RecyclerView,它返回一个具有ViewPager的视图(挑战); 项目视图(挑战)需要一个适配器到它可以修改的ViewPager(解决方案)。

答案 1 :(得分:0)

对Marcus的解释并非100%清楚,但它让我思考并让我更好地理解了viewpager / adapter链接。我删除了cardview pard,我是一个普通的listview,里面有一个viewpager。这是代码的简短版本(缺少某些部分!)。

在片段中,我制作了一个自定义数据类的列表。列表的每个部分代表1行。该列表将添加到自定义适配器(代码如下),此自定义适配器将添加到列表视图(mylistview)。

<强> Fragment.java

List<ChallengesData> rowItems;
ListView mylistview;


    @Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container,
                         Bundle savedInstanceState) {
    final View rootView = inflater.inflate(R.layout.fragment_challenges_overview, container, false);
    rowItems = new ArrayList<ChallengesData>();

    final SolutionsAdapter adapter = new SolutionsAdapter(getContext(), rowItems);
    mylistview = (ListView) rootView.findViewById(R.id.LVChallenges);
    mylistview.setAdapter(adapter);
    mylistview.setOnItemClickListener(this);

    ChildEventListener childEventListener = new ChildEventListener() { 
        @Override
        public void onChildAdded(DataSnapshot dataSnapshot, String previousChildName) { 
            final String challengeKey = dataSnapshot.getKey();
            DatabaseReference groupKeyRef = rootRef.child(....).child(challengeKey);

            groupKeyRef.addValueEventListener(new ValueEventListener() { 
                @Override
                public void onDataChange(DataSnapshot dataSnapshot) {
                    String description = dataSnapshot.child("description").getValue(String.class);
                    String title = dataSnapshot.child("title").getValue(String.class);

                    ChallengesData data = new ChallengesData(title,description,challengeKey);
                    int dataIndex = findDataitem(rowItems,challengeKey);
                    if(dataIndex == -1){
                        //group not yet added so add group
                        rowItems.add(data);
                    }
                    else{
                        rowItems.set(dataIndex,data);
                    }
                    adapter.notifyDataSetChanged();
                }

                @Override
                public void onCancelled(DatabaseError databaseError) {}
            });
        }

              "here were other @override functions"
    };
    userChallengeRef.addChildEventListener(childEventListener);

    return rootView;
}

xml中的listview:

    <ListView
    android:id="@+id/LVChallenges"
    android:scrollbars="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
</ListView>

<强> SolutionsAdapter.xml

在构造函数中,获取上下文,以便我们可以在正确的位置充气并获取listview所需的项目。在viewpager中扩展所需的布局,将值分配给布局。然后为viewpager项目(myViewpagerlist)创建列表,将视图(convertview)提供给自定义适配器(vpadapter),以便它可以在正确的位置上充气。创建一个新的viewpager,向其添加layout元素并向其添加自定义适配器(vpadapter)。填写viewpager(myviewpagerlist)的列表并调用notifyDataSetChanged()函数。

    Context context;
List<ChallengesData> rowItems;
LayoutInflater mInflater;

SolutionsAdapter(Context context, List<ChallengesData> rowItems) {
    this.context = context;
    this.rowItems = rowItems;
    mInflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
}


/* private view holder class */
private class ViewHolder {
    TextView title;
    TextView description;

}

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

    ViewHolder holder = null;
    ChallengesData row_pos = rowItems.get(position);
    //LayoutInflater mInflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
    if (convertView == null) {


        convertView = mInflater.inflate(R.layout.row, null);
        holder = new ViewHolder();

        holder.title = (TextView) convertView.findViewById(R.id.txtTitle);
        holder.description = (TextView) convertView.findViewById(R.id.txtDescription);


        convertView.setTag(holder);
    } else {
        holder = (ViewHolder) convertView.getTag();
    }
    holder.title.setText(row_pos.getTitle());
    holder.description.setText(row_pos.getDescription());

    //List inside viewpager
    final ArrayList<SolutionsData> myViewPagerList = new ArrayList<SolutionsData>();
    final VPadapter myVPadapter = new VPadapter(convertView.getContext(),myViewPagerList);

    final ViewPager myViewPager;
    myViewPager = (ViewPager) convertView.findViewById(R.id.view_pager);
    myViewPager.setAdapter(myVPadapter);

    DatabaseReference challengeSolRef = rootRef.child("...."); 
    challengeSolRef.addChildEventListener(new ChildEventListener() {
        @Override
        public void onChildAdded(DataSnapshot dataSnapshot, String s) {
            DatabaseReference SolutionRef = rootRef.child("..."); 
            SolutionRef.addValueEventListener(new ValueEventListener() {
                @Override
                public void onDataChange(DataSnapshot dataSnapshot) {
                    final String solutionsKey = dataSnapshot.getKey();
                    final String userID = dataSnapshot.child("userId").getValue(String.class);
                    final String description = dataSnapshot.child("description").getValue(String.class);

                    //get file from cloud
                    storageRef.child("....").getBytes(Long.MAX_VALUE).addOnSuccessListener(new OnSuccessListener<byte[]>() {
                        @Override
                        public void onSuccess(byte[] bytes) {
                            // Use the bytes to display the image
                            Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
                            SolutionsData solData = new SolutionsData(solutionsKey,userID,description,bytes);
                            int rowItemIndex = findSolutionIitem(myViewPagerList,solutionsKey);
                            if(rowItemIndex == -1){
                                //group not yet added so add group
                                myViewPagerList.add(solData);
                            }
                            else{
                                myViewPagerList.set(rowItemIndex,solData);
                            }
                            myVPadapter.notifyDataSetChanged();
                        }
                    }).addOnFailureListener(new OnFailureListener() {
                        @Override
                        public void onFailure(@NonNull Exception exception) {                                // Handle any errors
                        }
                    });
                }

                @Override
                public void onCancelled(DatabaseError databaseError) {

                }
            });
        }
    });

<强> VPAdapter.java 创建一个新视图,为其分配正确的数据并完成。

class VPadapter extends PagerAdapter{
// This holds all the currently displayable views, in order from left to right.
private ArrayList<SolutionsData> views;

Context context;
LayoutInflater mInflater;

VPadapter(Context context, ArrayList<SolutionsData> myViewPagerList) {
    this.context = context;
    this.views = myViewPagerList;
    mInflater = (LayoutInflater) context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
}
//-----------------------------------------------------------------------------
// Used by ViewPager.  "Object" represents the page; tell the ViewPager where the
// page should be displayed, from left-to-right.  If the page no longer exists,
// return POSITION_NONE.
@Override
public int getItemPosition (Object object)
{
    int index = views.indexOf (object);
    if (index == -1)
        return POSITION_NONE;
    else
        return index;
}

//-----------------------------------------------------------------------------
// Used by ViewPager.  Called when ViewPager needs a page to display; it is our job
// to add the page to the container, which is normally the ViewPager itself.  Since
// all our pages are persistent, we simply retrieve it from our "views" ArrayList.
@Override
public Object instantiateItem (ViewGroup container, int position)
{
    SolutionsData row_pos = views.get(position);

    View v = mInflater.inflate(R.layout.solutions,null);
    TextView SIDview = (TextView) v.findViewById(R.id.txtSolutionID);
    SIDview.setText(row_pos.getSolutionKey());
    Image.setImageBitmap(row_pos.getSolutionImageBitmap());
    container.addView (v);

    return v;
}

//-----------------------------------------------------------------------------
// Used by ViewPager.  Called when ViewPager no longer needs a page to display; it
// is our job to remove the page from the container, which is normally the
// ViewPager itself.  Since all our pages are persistent, we do nothing to the
// contents of our "views" ArrayList.
@Override
public void destroyItem (ViewGroup container, int position, Object object)
{
    container.removeView ((View) object);
}

//-----------------------------------------------------------------------------
// Used by ViewPager; can be used by app as well.
// Returns the total number of pages that the ViewPage can display.  This must
// never be 0.
@Override
public int getCount ()
{
    return views.size();
}

//-----------------------------------------------------------------------------
// Used by ViewPager.
@Override
public boolean isViewFromObject (View view, Object object)
{
    return view == object;
}

}
相关问题