DeG*_*seZ 8 android firebase android-cardview firebase-realtime-database firebase-storage
我有一份清单CardViews.每个CardView(代表挑战)都有一个ViewPager显示"解决方案"的垂直可扫描列表.
"解决方案列表"中的数据和图像来自Firebase数据库.
我遇到的问题是您打开的第一个CardView(当您单击它时,它会展开并显示解决方案)会正确显示所有解决方案.当你点击第二个时,它会扩展但没有显示数据,我认为它是这样的,因为我必须使用"最终"布局(final FrameLayout v0 = (FrameLayout) inflater.inflate(R.layout.solutions, null);)
以下是自定义RecyclerView适配器的重要部分的片段.
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());
}
});
}
....
});
....
}
});
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是challenge_row.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>
Run Code Online (Sandbox Code Playgroud)
这是solutions.xml:
<?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>
Run Code Online (Sandbox Code Playgroud)
根据马科斯的建议编辑:(仍然是相同的结果)
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(final RecyclerItemViewHolder holder, final int position) {
holder.etTitleTextView.setText(myChallengesList.get(position).getTitle());
holder.etDescriptionTextView.setText(myChallengesList.get(position).getDescription());
mLastPosition =position;
holder.mainLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(holder.itemView.getContext(), "Position:" + myChallengesList.get(holder.getAdapterPosition()).getDescription(), Toast.LENGTH_SHORT).show();
//create reference to solutions inside challenges data
challengeSolutionsRef = challengeSolutionsRef.child(myChallengesList.get(holder.getAdapterPosition()).getChallengeKey()).child("solutions");
challengeSolutionsRef.addChildEventListener(new ChildEventListener() {
@Override
public void onChildAdded(DataSnapshot dataSnapshot, String previousChildName) {
DatabaseReference solutionsRef = rootRef.child("solutions").child(dataSnapshot.getKey());
solutionsRef.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
holder.v0 = (FrameLayout) holder.myInflater.inflate(R.layout.solutions, null);
TextView TVSolutionID = (TextView)holder.v0.findViewById(R.id.txtSolutionID);
TextView TVUserID = (TextView)holder.v0.findViewById(R.id.txtUserID);
TVSolutionID.setText(dataSnapshot.getKey());
String UserID = dataSnapshot.child("userId").getValue(String.class);
TVUserID.setText(UserID);
holder.myChallengesPagerAdapter.notifyDataSetChanged();
storageRef.child("Solutions/").child(dataSnapshot.child("picture").getValue("filename").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)holder.v0.findViewById(R.id.ivSolutionImage);
IVSolution.setImageBitmap(bitmap);
holder.myChallengesPagerAdapter.notifyDataSetChanged();
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception exception) {
// Handle any errors
//Create new item in the rowItems arraylist to add to the listview
ImageView IVSolution = (ImageView)holder.v0.findViewById(R.id.ivSolutionImage);
IVSolution.setImageResource(R.mipmap.ic_challenger_black);
holder.myChallengesPagerAdapter.notifyDataSetChanged();
}
});
holder.myChallengesPagerAdapter.addView(holder.v0);
holder.myChallengesPagerAdapter.notifyDataSetChanged();
}
@Override
public void onCancelled(DatabaseError databaseError) {
Log.d("Test","The read failed: " + databaseError.getCode());
}
});
}
...
});
});
}
@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 TextView etTitleTextView;
private TextView etDescriptionTextView;
//private final TextView etContent;
private ChallengesPagerAdapter myChallengesPagerAdapter;
private ViewPager myViewPager;
private FrameLayout myFrameLayout;
private LinearLayout mainLayout;
private View myParent;
private LayoutInflater myInflater;
private FrameLayout v0;
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);
myParent = parent;
myInflater = (LayoutInflater)parent.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
}
}
Run Code Online (Sandbox Code Playgroud)
Marcus 的解释对我来说并不是 100% 清楚,但它让我思考并让我更好地理解了 viewpager/adapter 链接。我删除了cardview pard,并使用了一个普通的列表视图,里面有一个viewpager。这是代码的简短版本(缺少某些部分!)。
在片段中,我列出了自定义数据类的列表。列表的每个部分代表 1 行。该列表将添加到自定义适配器(代码如下),并且此自定义适配器将添加到列表视图(mylistview)。
片段.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;
}
Run Code Online (Sandbox Code Playgroud)
xml中的列表视图:
<ListView
android:id="@+id/LVChallenges"
android:scrollbars="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</ListView>
Run Code Online (Sandbox Code Playgroud)
解决方案适配器.xml
在构造函数中,获取上下文,以便我们可以在正确的位置进行膨胀并获取列表视图所需的项目。在 viewpager 中膨胀您想要的布局,并将值分配给布局。然后为 viewpager 项目创建列表 (myViewpagerlist),将视图 (convertview) 提供给自定义适配器 (vpadapter),以便它可以在正确的位置膨胀。创建一个新的 viewpager,向其中添加布局元素并向其中添加自定义适配器 (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) {
}
});
}
});
Run Code Online (Sandbox Code Playgroud)
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;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
622 次 |
| 最近记录: |