我想知道如何使用recycleler和cardview实现一个标签式活动(4个片段),连接到firebase数据库以提取数据。
- 我是否必须为每个片段或相同的适配器创建一个适配器,但每个片段都会过滤它需要的数据?
- 我是否必须从主Activity调用getInstance并引用Firebase DB? 我对recyclerView完全不熟悉,请告诉我每一个可能的细节。
- 对于cardview,将创建一个名为“property”,2 textview和1 imageview的对象。这将如何适合整个代码,我的意思是属性类及其实例。
- 我可以在Firebase存储中存储将在cardview中使用的图像吗?如果是这样,如何查询它们?
这是代码
package com.realty.drake.kunuk;
import android.support.design.widget.TabLayout;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
public class MainActivity extends AppCompatActivity {
/**
* The {@link android.support.v4.view.PagerAdapter} that will provide
* fragments for each of the sections. We use a
* {@link FragmentPagerAdapter} derivative, which will keep every
* loaded fragment in memory. If this becomes too memory intensive, it
* may be best to switch to a
* {@link android.support.v4.app.FragmentStatePagerAdapter}.
*/
private SectionsPagerAdapter mSectionsPagerAdapter;
/**
* The {@link ViewPager} that will host the section contents.
*/
private ViewPager mViewPager;
@Override
protected void onCreate(Bundle savedInstanceState) {
Log.d("debugg", "OnCreate started");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// Create the adapter that will return a fragment for each of the three
// primary sections of the activity.
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(mViewPager);
mViewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mViewPager));
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* A {@link FragmentPagerAdapter} that returns a fragment corresponding to
* one of the sections/tabs/pages.
*/
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
Log.d("DEBUGG","getItem called" );
//Returning the current tab
switch (position) {
case 0:
Tab1Buy tab1 = new Tab1Buy();
return tab1;
case 1:
Tab2Rent tab2 = new Tab2Rent();
return tab2;
case 2:
Tab3Lot tab3 = new Tab3Lot();
return tab3;
case 3:
Tab4Saved tab4 = new Tab4Saved();
return tab4;
default:
return null;
}
}
@Override
public int getCount() {
// Show 4 total pages.
return 4;
}
@Override
public CharSequence getPageTitle(int position){
Log.d("Debugg", "getPageTitle: Executed");
switch (position) {
case 0:
return "BUY";
case 1:
return "RENT";
case 2:
return "LOT";
case 3:
return "SAVED";
}
return null;
}
}
}
package com.realty.drake.kunuk;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
/**
* Created by drake on 4/11/18.
*/
public class Tab1Buy extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.tab1buy, container, false);
return rootView;
}
}
package com.realty.drake.kunuk;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
/**
* Created by drake on 4/11/18.
*/
public class Tab2Rent extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.tab2rent, container, false);
return rootView;
}
}
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="com.realty.drake.kunuk.MainActivity">
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="@dimen/appbar_padding_top"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_weight="1"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="@style/AppTheme.PopupOverlay"
app:title="@string/app_name">
</android.support.v7.widget.Toolbar>
<android.support.design.widget.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMaxWidth="0dp"
app:tabGravity="fill"
app:tabMode="fixed">
<android.support.design.widget.TabItem
android:id="@+id/tabItem"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/tab_text_1" />
<android.support.design.widget.TabItem
android:id="@+id/tabItem2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/tab_text_2" />
<android.support.design.widget.TabItem
android:id="@+id/tabItem3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/tab_text_3" />
</android.support.design.widget.TabLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end|bottom"
android:layout_margin="@dimen/fab_margin"
app:srcCompat="@android:drawable/ic_dialog_email" />
</android.support.design.widget.CoordinatorLayout>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#dfdfdf"
android:orientation="vertical">
<!-- TODO Add white icon -->
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/tools"
android:id="@+id/property"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:cardUseCompatPadding="true"
card_view:cardCornerRadius="4dp"
card_view:cardElevation="4dp">
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="290dp"
android:orientation="vertical">
<ImageView
android:id="@+id/post_image"
android:contentDescription="@string/property"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="71dp"
android:scaleType="centerCrop"
android:src="@drawable/house1"
app:layout_constraintBottom_toTopOf="@+id/number_bedroom"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/post_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginStart="5dp"
android:layout_marginTop="8dp"
android:text="55,000$"
android:textColor="@color/colorPrimary"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.79" />
<TextView
android:id="@+id/post_desc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:layout_marginStart="5dp"
android:layout_marginTop="1dp"
android:text="23,Rue Duvivier-hall, Les Cayes, "
android:textColor="#737373"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/post_title"
app:layout_constraintVertical_bias="0.0" />
<ImageView
android:id="@+id/bathroom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:layout_marginStart="100dp"
android:layout_marginTop="2dp"
android:background="#ff9100"
android:src="@drawable/bathtub"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.976" />
<ImageView
android:id="@+id/bedroom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:layout_marginStart="25dp"
android:layout_marginTop="2dp"
android:background="#ff9100"
android:src="@drawable/bedroom"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.976" />
<TextView
android:id="@+id/number_bathroom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:text="2"
android:textColor="#ff9100"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="@+id/bathroom"
app:layout_constraintEnd_toStartOf="@+id/bathroom" />
<TextView
android:id="@+id/number_bedroom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:text="3"
android:textColor="#ff9100"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="@+id/bedroom"
app:layout_constraintEnd_toStartOf="@+id/bedroom" />
<TextView
android:id="@+id/number_garage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:text="1"
android:textColor="#ff9100"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="@+id/garage"
app:layout_constraintEnd_toStartOf="@+id/garage" />
<ImageView
android:id="@+id/garage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:layout_marginStart="175dp"
android:layout_marginTop="2dp"
android:background="#ff9100"
android:src="@drawable/garage"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.976" />
</android.support.constraint.ConstraintLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
<?xml version="1.0" encoding="utf-8"?>
<!--TODO add recyclerView layout-->
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/rv_items">
</android.support.v7.widget.RecyclerView>
</FrameLayout>
感谢您的帮助
答案 0 :(得分:1)
-我是否必须为每个片段或同一适配器创建一个适配器,但是每个片段将过滤所需的数据? 答:我让每个片段都有自己对firebase数据库的引用,每个片段都查询一个孩子。在firebase数据库中,查看图像,每个Fragment都调用一个孩子:“买,买,租”。
-我是否必须从主Activity调用getInstance并引用Firebase DB?我对recyclerView完全陌生,请提供所有可能的详细信息。
A:我改为在每个片段中调用getIntance,
public class Tab1Buy extends Fragment {
private DatabaseReference propertyRef;
private RecyclerView mPropertyRecyclerView;
FirebaseRecyclerAdapter<Property, PropertyViewHolder> mPropertyAdapter;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.property_tab, container, false);
mPropertyRecyclerView = rootView.findViewById(R.id.property_recyclerView);
return rootView;
}
//TODO Check internet and display error msg if internet down
@Override
public void onViewCreated(final View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
mPropertyRecyclerView.hasFixedSize();
mPropertyRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
final ProgressBar progressBar = view.findViewById(R.id.progressBar);
progressBar.setVisibility(View.VISIBLE);
propertyRef = FirebaseDatabase.getInstance()
.getReference()
.child("Buy");
propertyRef.keepSynced(true);
// keyQuery - the Firebase location containing the list of keys to be found in dataRef
//Query personQuery = propertyRef.orderByKey();
FirebaseRecyclerOptions<Property> options =
new FirebaseRecyclerOptions.Builder<Property>()
.setQuery(propertyRef, Property.class)
.build();
mPropertyAdapter = new FirebaseRecyclerAdapter<Property, PropertyViewHolder>(options) {
@Override
// Bind the Property object to the ViewHolder PropertyHolder
public void onBindViewHolder(@NonNull PropertyViewHolder holder,
final int position, @NonNull final Property model) {
holder.setPrice(model.getPrice());
holder.setAddress(model.getAddress());
holder.setNumberOfBed(model.getNumberOfBed());
holder.setNumberOfBath(model.getNumberOfBath());
holder.setNumberOfCar(model.getNumberOfCar());
holder.setPropertyImage(model.getPropertyImage());
//This Intent send Parcelable from Property to PropertyDetail
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
getActivity().startActivity(new Intent(getActivity(), PropertyDetail.class)
.putExtra("Property", model));
}
});
}
@Override
public PropertyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// Create a new instance of the ViewHolder, in this case we are using a custom
// layout called R.layout.property_card for each item
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.property_card, parent, false);
return new PropertyViewHolder(view);
}
@Override
public void onDataChanged() {
// Called each time there is a new data snapshot. You may want to use this method
// to hide a loading spinner or check for the "no documents" state and update your UI.
// ...
progressBar.setVisibility(View.GONE);
}
//TODO Implement onError
@Override
public void onError(@NonNull DatabaseError e) {
// Called when there is an error getting data. You may want to update
// your UI to display an error message to the user.
// ...
progressBar.setVisibility(View.GONE);
Toast.makeText(getActivity(), "DatabaseError", Toast.LENGTH_SHORT).show();
}
};
mPropertyRecyclerView.setAdapter(mPropertyAdapter);
}
@Override
public void onStart() {
super.onStart();
mPropertyAdapter.startListening();
}
@Override
public void onStop() {
super.onStop();
mPropertyAdapter.stopListening();
}
public class PropertyViewHolder extends RecyclerView.ViewHolder {
View mView;
public PropertyViewHolder(View itemView) {
super(itemView);
mView = itemView;
}
public void setPrice(int price) {
String currencyPrice = NumberFormat //Format the price variable in currency form
.getCurrencyInstance(Locale.US)
.format(price);
TextView Price = mView.findViewById(R.id.post_price);
Price.setText(currencyPrice);
}
public void setAddress(String address){
TextView Address = mView.findViewById(R.id.post_address);
Address.setText(String.valueOf(address));
}
public void setNumberOfBed(int numberOfBed){
TextView NumberOfBed = mView.findViewById(R.id.post_bedroom);
NumberOfBed.setText(String.valueOf(numberOfBed));
}
public void setNumberOfBath(int numberOfBath){
TextView NumberOfBath = mView.findViewById(R.id.post_bathroom);
NumberOfBath.setText(String.valueOf(numberOfBath));
}
public void setNumberOfCar(int numberOfCar) {
TextView NumberOfCar = mView.findViewById(R.id.post_garage);
NumberOfCar.setText(String.valueOf(numberOfCar));
}
public void setPropertyImage(String propertyImage){
ImageView imageView = mView.findViewById(R.id.post_propertyImage);
//take one long string containing multiple url in and parse it
String propertyImageArray[] = propertyImage.split(",");
//Loading circle for placeholder, ColorAccent has been used
CircularProgressDrawable progressDrawable =
new CircularProgressDrawable(getContext());
progressDrawable.setStrokeWidth(5f);
progressDrawable.setCenterRadius(30f);
progressDrawable.setColorSchemeColors(Color.argb(1,255,145,0));
progressDrawable.start();
// Download directly from StorageReference using Glide
// (See MyAppGlideModule for Loader registration)
GlideApp.with(getContext())
.load(propertyImageArray[0])
.placeholder(progressDrawable)
.fitCenter()
.into(imageView);
}
}
}
-对于卡片视图,将创建一个名为“属性”,2个文本视图和1个图像视图的对象。这是如何适合整个代码的,我的意思是属性类及其实例。
A:创建ViewHolder的新实例,在这种情况下,我们为每个项目使用名为R.layout.property_card的自定义布局。查看上面的代码,特别是在该行public PropertyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
-我可以将要在cardview中使用的图像存储在Firebase Storage上吗?如果可以,如何查询它们?
A:是的,我将图像存储在Firebase Storage中,然后使用其生成的url传入Glide方法。看上面的代码。
我只显示第一个片段,因为它们看上去都差不多,除了firebase中的子引用不同。