im trying to get data from firestore. but those data don't appears in my fragment activity.
and there is this error: E/RecyclerView: No adapter attached; skipping layout
i can only see the background of frangment activy, where is the error?
SecondFragment.class
public class SecondFragment extends Fragment {
public static final String TAG = "FireLog";
RecyclerView mMainList;
FirebaseFirestore mFirestore;
CollectionReference mRef;
View view;
public List<Offices> officesList;
public OfficesListAdapter officesListAdapter;
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.second_layout, container, false);
//Recycler View
mMainList = (RecyclerView) view.findViewById(R.id.main_list);
LinearLayoutManager manager = new LinearLayoutManager(getContext());
mMainList.setHasFixedSize(true);
mMainList.setLayoutManager(new LinearLayoutManager(getContext()));
mMainList.setAdapter(officesListAdapter);
mFirestore = FirebaseFirestore.getInstance();
officesList = new ArrayList<>();
officesListAdapter = new OfficesListAdapter(officesList);
mFirestore.collection("TICINO").addSnapshotListener(new EventListener<QuerySnapshot>() {
#Override
public void onEvent(#javax.annotation.Nullable QuerySnapshot queryDocumentSnapshots, #javax.annotation.Nullable FirebaseFirestoreException e) {
if (e != null){
Log.d(TAG, "Error : " + e.getMessage());
}
for (DocumentChange doc: queryDocumentSnapshots.getDocumentChanges()) {
if(doc.getType() == DocumentChange.Type.ADDED){
Offices offices = doc.getDocument().toObject(Offices.class);
officesList.add(offices);
officesListAdapter.notifyDataSetChanged();
}
}
}
});
second_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<android.support.v7.widget.RecyclerView
android:id="#+id/main_list"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
OfficeListAdapter.class
public class OfficesListAdapter extends RecyclerView.Adapter<OfficesListAdapter.ViewHolder> {
public List<Offices> officesList;
public OfficesListAdapter(List<Offices> officesList){
this.officesList = officesList;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.list_offices, viewGroup, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder viewHolder, int i) {
viewHolder.nameText.setText(officesList.get(i).getNameOffices());
viewHolder.cambioText.setText(officesList.get(i).getCambio());
}
#Override
public int getItemCount() {
return officesList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView nameText;
public TextView cambioText;
View mView;
public ViewHolder(#NonNull View itemView) {
super(itemView);
mView=itemView;
nameText = (TextView) mView.findViewById(R.id.text_view_name_office);
cambioText = (TextView) mView.findViewById(R.id.text_view_cambio_offices);
}
}
}
Offices.class
public class Offices {
String name, cambio;
public Offices(){}
public Offices(String name, String cambio) {
this.name = name;
this.cambio = cambio;
}
public String getNameOffices() {
return name;
}
public void setNameOffices(String name) {
this.name = name;
}
public String getCambio() {
return cambio;
}
public void setCambio(String cambio) {
this.cambio = cambio;
}
}
list_offices.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_marginTop="8dp"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
app:cardBackgroundColor="#ffffe8">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="8dp">
<TextView
android:id="#+id/text_view_name_office"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Title"
android:layout_alignParentLeft="true"
android:maxLines="1"
android:ellipsize="end"
android:textAppearance="#style/TextAppearance.AppCompat.Large" />
<TextView
android:id="#+id/text_view_cambio_offices"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:text="Description"
android:layout_below="#id/text_view_name_office"/>
</RelativeLayout>
</android.support.constraint.ConstraintLayout>
Try to set the adapter after instantiating it. E.g.:
// Inside OnCreate
//Recycler View
mMainList = (RecyclerView) view.findViewById(R.id.main_list);
LinearLayoutManager manager = new LinearLayoutManager(getContext());
mMainList.setHasFixedSize(true);
mMainList.setLayoutManager(new LinearLayoutManager(getContext()));
mFirestore = FirebaseFirestore.getInstance();
officesList = new ArrayList<>();
officesListAdapter = new OfficesListAdapter(officesList);
// Here your adapter is initialised
mMainList.setAdapter(officesListAdapter);
Create your adapter object before set it on RecyclerView
// add below method in your adapter class
public void dataChanged(List<Offices> officesList){
this.officesList = officesList;
notifyDataSetChanged();// make sure dont forget to call this method
}
// create adapter object before set it on RecyclerView
LinearLayoutManager manager = new LinearLayoutManager(getContext());
mMainList.setHasFixedSize(true);
mMainList.setLayoutManager(new LinearLayoutManager(getContext()));
officesListAdapter = new OfficesListAdapter(null);// add this line here
mMainList.setAdapter(officesListAdapter);
mFirestore = FirebaseFirestore.getInstance();
officesList = new ArrayList<>();
// and finally update data on your adapter from your firebase onEvent() method
for (DocumentChange doc: queryDocumentSnapshots.getDocumentChanges()) {
if(doc.getType() == DocumentChange.Type.ADDED){
Offices offices = doc.getDocument().toObject(Offices.class);
officesList.add(offices);
}
}
officesListAdapter.dataChanged(officesList);// update from here
Related
Well i think i got everything as they should be , i don't really know what i did wrong with the recycler but i still go error like "No adapter attached; skipping layout"
I NOTICED THAT ON UsersAdapter.java on the line "itemView.setOnClickListener(view -> onUserClickListener.onUserClicked(getAdapterPosition()));". getadapterposition is deprecated. Would that be the problem ?
Usersadapter.java
public class UsersAdapter extends RecyclerView.Adapter<UsersAdapter.UserHolder> {
private final ArrayList<User> users;
private final Context context;
private final OnUserClickListener onUserClickListener;
public UsersAdapter(ArrayList<User> users, Context context, OnUserClickListener onUserClickListener) {
this.users = users;
this.context = context;
this.onUserClickListener = onUserClickListener;
}
interface OnUserClickListener{
void onUserClicked(int position);
}
#NonNull
#Override
public UserHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.user_holder,parent, false);
return new UserHolder(view);
}
#Override
public void onBindViewHolder(#NonNull UserHolder holder, int position) {
holder.txtUsername.setText(users.get(position).getUsername());
Glide.with(context).load(users.get(position).getProfile_img()).error(R.drawable.account_img).placeholder(R.drawable.account_img).into(holder.profile_thumbnail);
}
#Override
public int getItemCount() {
return users.size();
}
class UserHolder extends RecyclerView.ViewHolder{
TextView txtUsername ;
ImageView profile_thumbnail;
public UserHolder(#NonNull View itemView){
super(itemView);
itemView.setOnClickListener(view -> onUserClickListener.onUserClicked(getAdapterPosition()));
txtUsername = itemView.findViewById(R.id.txtUsername);
profile_thumbnail = itemView.findViewById(R.id.profile_thumbnail);
}
}
}
user_holder.xml
<androidx.cardview.widget.CardView
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
app:cardBackgroundColor="#color/Color_grey"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="10dp"
android:layout_marginTop="10dp"
app:cardCornerRadius="14dp"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="7dp">
<androidx.cardview.widget.CardView
android:layout_width="70dp"
app:cardCornerRadius="180dp"
android:layout_height="70dp">
<ImageView
android:id="#+id/profile_thumbnail"
android:scaleType="centerCrop"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</androidx.cardview.widget.CardView>
<TextView
android:id="#+id/txtUsername"
android:layout_width="wrap_content"
android:layout_marginStart="20dp"
android:layout_gravity="center"
android:textColor="#color/white"
android:layout_height="wrap_content"
/>
</LinearLayout>
</androidx.cardview.widget.CardView>
activity_friends.xml
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
/>
FriendsActivity.java
public class FriendsActivity extends AppCompatActivity {
private RecyclerView recyclerView;
private ArrayList<User> users;
private ProgressBar progressBar_connectivity;
private UsersAdapter userAdapter;
UsersAdapter.OnUserClickListener onUserClickListener;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_friends);
progressBar_connectivity = findViewById(R.id.progressBar_connectivity);
users = new ArrayList<>();
recyclerView = findViewById(R.id.recycler);
onUserClickListener = position -> Toast.makeText(FriendsActivity.this,"Tapped this User "+users.get(position).getUsername(),Toast.LENGTH_SHORT).show();
getUsers();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.profile_menu,menu);
return true;
}
#Override
public boolean onOptionsItemSelected(#NonNull MenuItem item){
if(item.getItemId() == R.id.menu_item_profile){
startActivity(new Intent(FriendsActivity.this, Profile.class));
}
return super.onOptionsItemSelected(item);
}
private void getUsers(){
FirebaseDatabase.getInstance().getReference("user").addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
for (DataSnapshot dataSnapshot : snapshot.getChildren()){
users.add(dataSnapshot.getValue(User.class));
}
userAdapter = new UsersAdapter(users, FriendsActivity.this,onUserClickListener);
recyclerView.setLayoutManager(new LinearLayoutManager(FriendsActivity.this));
recyclerView.setHasFixedSize(true);
recyclerView.setAdapter(userAdapter);
userAdapter.notifyDataSetChanged();
progressBar_connectivity.setVisibility(View.GONE);
recyclerView.setVisibility(View.VISIBLE);
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
}
I did try to add on my code this one , i saw from an other topic-question , but it didn't help , i did even move the getUsers(); on any other caller except onCreate, still same results.
llm.setOrientation(LinearLayoutManager.VERTICAL);
list.setLayoutManager(llm);
list.setAdapter( adapter );
I know that my question has been asked several times but i have been searching for a while and none of all the answers fixed my problem.
The issue is that when i create the recyclerview adapter and all the stuff in the method "onViewCreated" in my "HomeFragment" i am not having any compilation error but my recyclerview doesn't load any image since none of the methods Overriden in recyclerview adapter are called even when i call "mAdapter.notifyDataSetChanged()"
HomeFragment.java
public class HomeFragment extends Fragment implements Response.Listener<GalleryItem[]>, Response.ErrorListener {
RequestQueue requestQueue;
List<GalleryItem> myDataset = new ArrayList<>();
RecyclerView mRecyclerView;
RecyclerView.Adapter mAdapter;
RecyclerView.LayoutManager mLayoutManager;
CustomJsonObjectRequest jsonObjectRequest;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(#NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.home_fragment, container, false);
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
mRecyclerView = view.findViewById(R.id.my_recycler_view);
mRecyclerView.setHasFixedSize(true);
mAdapter = new GalleryAdapter(myDataset);
mLayoutManager = new LinearLayoutManager(getActivity());
mRecyclerView.setLayoutManager(mLayoutManager);
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
mRecyclerView.setAdapter(mAdapter);
jsonObjectRequest = new CustomJsonObjectRequest(Constants.HOME_URL, GalleryItem[].class, this, this);
requestQueue = VolleySingleton.getInstance(this.getContext()).getRequestQueue();
VolleySingleton.getInstance(this.getContext()).addToRequestQueue(jsonObjectRequest, "headerRequest");
}
#Override
public void onResponse(GalleryItem[] response) {
myDataset = Arrays.asList(response);
mAdapter.notifyDataSetChanged();
}
#Override
public void onErrorResponse(VolleyError error) {
Log.d(Constants.API_ERROR_TAG, error.getMessage());
}
GalleryAdapter.java
public class GalleryAdapter extends RecyclerView.Adapter<GalleryAdapter.MyViewHolder> {
private List<GalleryItem> mDataset;
public static class MyViewHolder extends RecyclerView.ViewHolder {
ImageView imageView;
public MyViewHolder(#NonNull View itemView) {
super(itemView);
Log.d("tagdetest2","myviewholder");
imageView = itemView.findViewById(R.id.gallery_image);
}
}
public GalleryAdapter(List<GalleryItem> myDataset) {
mDataset = myDataset;
}
#NonNull
#Override
public GalleryAdapter.MyViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int i) {
Log.d("tagdetest2","onCreateViewHolder");
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_gallery, parent, false);
return new MyViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull GalleryAdapter.MyViewHolder myViewHolder, int i) {
Log.d("tagdetest2", mDataset.get(i).link);
Glide.with(myViewHolder.itemView.getContext()).load(mDataset.get(i).link).into(myViewHolder.imageView);
}
#Override
public int getItemCount() {
Log.d("tagdetest", "size = " + mDataset.size());
return mDataset.size();
}
item_gallery.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:id="#+id/gallery_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
home_fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<android.support.v7.widget.RecyclerView
android:id="#+id/my_recycler_view"
android:scrollbars="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</android.support.constraint.ConstraintLayout>
myDataset = Arrays.asList(response);
overrides the reference, in your Fragment not in your adapter.
Try with
mDataset.addAll(Arrays.asList(response));
insetad
In this fragment,
public class BlankFragment extends Fragment {
public BlankFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
final View rootView = inflater.inflate(R.layout.fragment_blank, container, false);
RecyclerView rv = rootView.findViewById(R.id.rv_recycler_view);
rv.setNestedScrollingEnabled(false);
SimpleDateFormat localDateFormat = new SimpleDateFormat("HH:mm");
SunTimes suntime = SunTimes.compute().at(latlang.Lat,latlang.Lang).today().execute();
String sun_rise = localDateFormat.format(suntime.getRise());
String sun_set = localDateFormat.format(suntime.getSet());
Date sunnoon = suntime.getNoon();
System.out.println("SUNRISE "+ sun_rise);
TextView cityField = rootView.findViewById(R.id.tv_city);
TextView sunrise = rootView.findViewById(R.id.tv_sunrt);
TextView sunset = rootView.findViewById(R.id.tv_sunst);
cityField.setText("Hello World"); //Line 45
sunrise.setText(sun_rise);
sunset.setText(sun_set);
return rootView;
}
I am getting error:
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
at com.example.phocast.BlankFragment.onCreateView(BlankFragment.java:45)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:2354)
The question is while I have a normal string as a text, how it can get null point exception?
What am I doing wrong?
Update
the fragment_blank does not have the id, as its just an inflater:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/swiperefresh"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="#+id/rv_recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</android.support.v7.widget.RecyclerView>
</android.support.v4.widget.SwipeRefreshLayout>
</RelativeLayout>
That id is in item_blank.xml as:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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="120sp" >
<android.support.v7.widget.CardView
android:id="#+id/card_view"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_margin="10dp"
android:layout_height="120sp"
card_view:cardCornerRadius="4dp"
card_view:elevation="14dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/iv_image"
android:layout_width="120sp"
android:layout_height="fill_parent"
android:scaleType="fitStart"
card_view:srcCompat="#drawable/property_image_3">
</ImageView>
<TextView
android:id="#+id/tv_city"
android:layout_width="wrap_content"
android:layout_height="30sp"
android:layout_marginBottom="1sp"
android:layout_toRightOf="#+id/iv_image"
android:gravity="top"
android:paddingLeft="5sp"
android:text="Hello World"
android:textAppearance="#style/TextAppearance.AppCompat.Large">
</TextView>
.....
and which is defined in the Adapter:
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
private String[] mDataset;
// Provide a reference to the views for each data item
// Complex data items may need more than one view per item, and
// you provide access to all the views for a data item in a view holder
public static class MyViewHolder extends RecyclerView.ViewHolder {
public CardView mCardView;
public TextView mTextView;
public MyViewHolder(View v) {
super(v);
mCardView = (CardView) v.findViewById(R.id.card_view);
mTextView = (TextView) v.findViewById(R.id.tv_city);
}
}
// Provide a suitable constructor (depends on the kind of dataset)
public MyAdapter(String[] myDataset) {
mDataset = myDataset;
}
// Create new views (invoked by the layout manager)
#Override
public MyAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
// create a new view
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.card_item, parent, false);
// set the view's size, margins, paddings and layout parameters
MyViewHolder vh = new MyViewHolder(v);
return vh;
}
#Override
public void onBindViewHolder(MyViewHolder holder, final int position) {
holder.mTextView.setText(mDataset[position]);
holder.mCardView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String currentValue = mDataset[position];
Log.d("CardView", "CardView Clicked: " + currentValue);
}
});
}
#Override
public int getItemCount() {
return mDataset.length;
}
}
So I am expecting the cardview to be read from the adapter, as it is working for this case:
public class BlankFragment extends Fragment {
public BlankFragment() {
// Required empty public constructor
}
//
// #Override
// public void onCreate(Bundle savedInstanceState) {
// super.onCreate(savedInstanceState);
//
// }
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
final View rootView = inflater.inflate(R.layout.fragment_blank, container, false);
RecyclerView rv = rootView.findViewById(R.id.rv_recycler_view);
rv.setNestedScrollingEnabled(false);
Weather_OWM.placeIdTask asyncTask = new Weather_OWM.placeIdTask(new Weather_OWM.AsyncResponse() {
public void processFinish(String weather_city, String weather_description, String weather_temperature, String weather_humidity, String weather_pressure, String weather_updatedOn, String weather_iconText, String sun_rise, String sun_set) {
TextView cityField = rootView.findViewById(R.id.tv_city);
TextView sunrise = rootView.findViewById(R.id.tv_sunrt);
TextView sunset = rootView.findViewById(R.id.tv_sunst);
cityField.setText(weather_city);
sunrise.setText(sun_rise);
sunset.setText(sun_set);
}
});
asyncTask.execute(Double.toString(latlang.Lat), Double.toString(latlang.Lang)); // asyncTask.execute("Latitude", "Longitude")
rv.setHasFixedSize(true);
MyAdapter adapter = new MyAdapter(new String[]{"Today", "Golden Hour", "Blue Hour", "Civil Twilight", "Nautical Twilight", "Astronomical Twilight", "Hello", "World"});
rv.setAdapter(adapter);
LinearLayoutManager llm = new LinearLayoutManager(getActivity());
rv.setLayoutManager(llm);
return rootView;
}
}
It's not about the string argument but the cityField TextView you're calling setText() on. You're initialising it with
rootView.findViewById(R.id.tv_city);
which returns null if the view is not found. So your fragment_blank layout does not have a view with id tv_city.
I am attempting to use the Swipecards library (https://github.com/Diolor/Swipecards) to build a tinder-esqe application. I am using a BaseAdapter to populate a layout with two text views and an image view that will be provided to the main SwipeFlingAdapterView. While both of the text fields are populated, I cannot get the image to appear on the cards. I have tried this implementation with both an ArrayAdapter and a BaseAdapter and the results are the same.
The activity layout (deal_page_layout)
<FrameLayout
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:layout_height="match_parent"
android:layout_width="match_parent">
<com.lorentzos.flingswipe.SwipeFlingAdapterView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/swipe_fling_view"
app:rotation_degrees="10"
tools:context=".DealPage"
android:alpha="1.0"
app:max_visible="2"
app:min_adapter_stack="5"/>
</FrameLayout>
The layout being populated by the BaseAdapter (deal_card)
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_height="match_parent"
android:layout_width="match_parent"
android:id="#+id/deal_card_image">
</ImageView>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/deal_card_title"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_margin="15dp"
android:gravity="center"
android:textSize="20dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/deal_card_description"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_margin="15dp"
android:gravity="center"
android:textSize="20dp"/>
</RelativeLayout>
BaseAdapter class
public class DealBaseAdapter extends BaseAdapter {
private Context context;
private List<GrubbyDeal> dealList;
private LayoutInflater li;
public DealBaseAdapter(Context context, LayoutInflater li, ArrayList<GrubbyDeal> dealList){
this.context = context;
this.dealList = dealList;
this.li = li;
}
#Override
public int getCount(){
return dealList.size();
}
#Override
public Object getItem(int position){
return dealList.get(position);
}
#Override
public long getItemId(int position){
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent){
ViewHolder viewHolder;
//resuse a view if possible
if(convertView == null){
convertView = li.inflate(R.layout.deal_card,parent,false);
viewHolder = new ViewHolder();
viewHolder.img = (ImageView) convertView.findViewById(R.id.deal_card_image);
viewHolder.title = (TextView) convertView.findViewById(R.id.deal_card_title);
viewHolder.desc = (TextView) convertView.findViewById(R.id.deal_card_description);
convertView.setTag(viewHolder);
}
else {
viewHolder = (ViewHolder) convertView.getTag();
}
GrubbyDeal curDeal = dealList.get(position);
viewHolder.img.setImageURI(curDeal.getImageUri());
viewHolder.title.setText(curDeal.getTitle());
viewHolder.desc.setText(curDeal.getDescription());
return convertView;
}
//view holder class to hold cached findViewByID results
private static class ViewHolder {
public ImageView img;
public TextView title;
public TextView desc;
}
And the main activity (DealPage)
public class DealPage extends Activity {
private ArrayList<GrubbyDeal> dealList;
private DealBaseAdapter dealAdapter;
SwipeFlingAdapterView flingContainer;
#Override
public void onCreate(Bundle sis){
super.onCreate(sis);
setContentView(R.layout.deal_page_layout);
//add some awesome cat deals to the adapter
dealList = new ArrayList<>();
for(int i=0; i < 5; i++){
GrubbyDeal tmp = new GrubbyDeal(i);
dealList.add(tmp);
}
//add another type of cat deal to the list
dealList.add(new GrubbyDeal());
dealAdapter = new DealBaseAdapter(this, getLayoutInflater(), dealList);
flingContainer = (SwipeFlingAdapterView) findViewById(R.id.swipe_fling_view);
flingContainer.setAdapter(dealAdapter);
flingContainer.setFlingListener(new SwipeFlingAdapterView.onFlingListener() {
#Override
public void removeFirstObjectInAdapter() {
// this is the simplest way to delete an object from the Adapter (/AdapterView)
Log.d("LIST", "removed object!");
GrubbyDeal popped = dealList.remove(0);
dealList.add(popped);
dealAdapter.notifyDataSetChanged();
}
#Override
public void onLeftCardExit(Object dataObject) {
makeToast(DealPage.this, "Left!");
}
#Override
public void onRightCardExit(Object dataObject) {
makeToast(DealPage.this, "Right!");
}
#Override
public void onAdapterAboutToEmpty(int itemsInAdapter) {
dealList.add(new GrubbyDeal());
dealAdapter.notifyDataSetChanged();
Log.d("LIST", "notified");
}
#Override
public void onScroll(float scrollProgressPercent) {
View view = flingContainer.getSelectedView();
}
});
flingContainer.setOnItemClickListener(new SwipeFlingAdapterView.OnItemClickListener() {
#Override
public void onItemClicked(int itemPosition, Object dataObject) {
makeToast(DealPage.this, "Clicked!");
}
});
}
}
Am I missing something obvious? Is there some vastly superior library that I should be using? Thanks,
Ian
I would recommend using Picasso to load images into your imageview.
Picasso.with(context).load(imgurl).into(viewHolder.img);
The problem was formatting. I was attempting to use
Uri.parse("android.resource://com.thepackage.theapp/R.drawable.cat4.jpg");
but wasn't getting a valid Uri back. So instead I am using resource ids with picasso and the card works great!
I have tried many ways to add recyclerview inside a fragment. I'm new for android. My android have 5 fragments one of these fragment I need to add a recyclerview. here is my code
notification_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/notification_item_root"
android:layout_width="match_parent"
android:layout_height="56dp"
android:gravity="center_vertical|left"
android:orientation="horizontal"
android:paddingLeft="16dp">
<de.hdodenhof.circleimageview.CircleImageView
android:id="#+id/notification_item_img"
android:layout_width="36dp"
android:layout_height="36dp"
android:src="#android:drawable/ic_input_get" />
<TextView
android:id="#+id/notification_item_text"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
android:paddingLeft="8dp"
android:text="Test Testre" />
</LinearLayout>
notification_Fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.app.AlertController.RecycleListView
android:id="#+id/notification_list"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
NotificationItem.java
public class NotificationItem {
private String title;
private int imageResId;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public int getImageResId() {
return imageResId;
}
public void setImageResId(int imageResId) {
this.imageResId = imageResId;
}
}
NotificationData.java
public class NotificationData {
private static final String[] textItem = {"pathum", "sai", "charu"};
private static final int[] imgItem = {android.R.drawable.ic_popup_reminder, android.R.drawable.ic_menu_add, android.R.drawable.ic_menu_delete};
public static List<NotificationItem> getListData() {
List<NotificationItem> data = new ArrayList<>();
for (int x = 0; x < 4; x++) {
for (int i = 0; i < textItem.length && i < imgItem.length; i++) {
NotificationItem item = new NotificationItem();
item.setImageResId(imgItem[i]);
item.setTitle(textItem[i]);
data.add(item);
}
}
return data;
}
}
NotificationAdapter.java
public class NotificationAdapter extends RecyclerView.Adapter<NotificationAdapter.NotificationHolder> {
private List<NotificationItem> listData;
private LayoutInflater inflater;
public NotificationAdapter(List<NotificationItem> listData, Context c) {
this.inflater = LayoutInflater.from(c);
this.listData = listData;
}
#Override
public NotificationHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = inflater.inflate(R.layout.notification_item,parent,false);
return new NotificationHolder(view);
}
#Override
public void onBindViewHolder(NotificationHolder holder, int position) {
NotificationItem item = listData.get(position);
holder.title.setText(item.getTitle());
holder.icon.setImageResource(item.getImageResId());
}
#Override
public int getItemCount() {
return listData.size();
}
class NotificationHolder extends RecyclerView.ViewHolder {
private TextView title;
private CircleImageView icon;
private View container;
public NotificationHolder(View itemView) {
super(itemView);
title = (TextView) itemView.findViewById(R.id.notification_item_text);
icon = (CircleImageView) itemView.findViewById(R.id.notification_item_img);
container = itemView.findViewById(R.id.notification_item_root);
}
}
}
NotificationFragment.java
public class NotificationFragment extends Fragment {
RecyclerView recyclerView;
NotificationAdapter notificationAdapter;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.notification_fragment, container, false);
recyclerView = (RecyclerView) rootView.findViewById(R.id.notification_list);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
notificationAdapter = new NotificationAdapter(NotificationData.getListData(),this);
recyclerView.setAdapter(notificationAdapter);
return rootView;
}
}
I was unable to make it right in NotificationFragment.java and NotificationAdapter.java please help me guys.
You are using wrong class for RecyclerView, instead of AlertController.RecyclerListView use this:
<!-- A RecyclerView with some commonly used attributes -->
<android.support.v7.widget.RecyclerView
android:id="#+id/my_recycler_view"
android:scrollbars="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
Here are some more informations:
RecyclerView
1) first add dependency to your app level gradle file then sync your project
compile 'com.android.support:recyclerview-v7:23.4.0'
2) go to your Layout file (eg: activity_main.xml) add recyclerview tag inside your base layout
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context="com.examples.rehan.excluzo.Fragments.OneFragment">
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="vertical"
android:id="#+id/recycler_view">
</android.support.v7.widget.RecyclerView>
3) create a class model.java and paste your code.
public class model{
private String name, gender;
public model() {
}
public model(String name, String gender) {
this.name= name;
this.gender= gender;
}
public String getGender() {
return gender;
}
public void setGender(String gneder) {
this.gender= gender;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name= name;
}
}
4)create xml file in your layout folder item_layout.xml and paste this code
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusable="true"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingTop="10dp"
android:paddingBottom="10dp" >
<TextView
android:id="#+id/name"
android:textColor="#color/title"
android:textSize="16dp"
android:textStyle="bold"
android:layout_alignParentTop="true"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/gender"
android:layout_below="#id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</RelativeLayout>
5)your need to create adapter to add child views to your listview. so create a file testAdapter.java file and paste this code.
here in list view i will be having only 2 items(eg : Name and gender)
public class testAdapter extends RecyclerView.Adapter<testAdapter.MyViewHolder> {
private List<model> productList;
Context context;
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_layout, parent, false);
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
model product = productList.get(position);
holder.name.setText(product.getName());
holder.gender.setText(product.getGender());
}
#Override
public int getItemCount() {
return productList.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder {
public TextView name,gender;
public MyViewHolder(View view) {
super(view);
name = (TextView) view.findViewById(R.id.name);
gender = (TextView) view.findViewById(R.id.gender);
}
}
public testAdapter(List<model> productList, Context context) {
this.productList = productList;
this.context = context;
}
}
6) now goto your MainActivity.java and paste this code
import android.content.Context;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private List<modle> movieList = new ArrayList<>();
private RecyclerView recyclerView;
private testAdapter mAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
mAdapter = new testAdapter(movieList);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(mAdapter);
preparedata();
}
private void preparedata() {
model movie = new model("XXX", "Male");
movieList.add(movie);
//add the items according to your wish
//name,gender
//here i have added all items with same name and gender. you can change it
model movie = new model("XXX", "Male");
movieList.add(movie);
model movie = new model("XXX", "Male");
movieList.add(movie);
model movie = new model("XXX", "Male");
movieList.add(movie);
model movie = new model("XXX", "Male");
movieList.add(movie);
model movie = new model("XXX", "Male");
movieList.add(movie);
model movie = new model("XXX", "Male");
movieList.add(movie);
mAdapter.notifyDataSetChanged();
}
}
Hope this helps :)