MY PROBLEM
All views inside my RecyclerView, I am talking about elements(TextView and ImageView ....) are displayed well, normal but when i want to list all items inside the recyclerView with this:
for(int i=0;i<recyclerView.getChildCount();i++){
ids=ids+"-"+recyclerView.getChildAt(i).getId();
}
when i display ids always show me the same id which is the RelativeLayout id and it supose to display the id of the elements inside the RecyclerView as the TextView, ImageView and more
MY RESEARCH
i was following a video from slidenerd of
RecyclerView.OnItemTouchListener
and for him is working fine i dont know why for my is not working i was reading a lot about my problem to find the exact problem because:
First thing i did change the ids names for all my layouts to be different
Move the position of my code
Confirm that the data sent by MotionEvent e.getX() and y.getY() was correct and even thought i change the methods for getRaw
Read about RecyclerView class and find that there is not issue in this method findChildVIewUnder because all things that do are mathematicals
Read the id number of each important resource in R file an then convert it to dec to compare the prompt
I am close to the frustation
MY CODE
teacher_item
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/problem"
android:layout_width="328dp"
android:layout_height="130dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="10dp"
android:clickable="true"
android:background="#drawable/borders">
<ImageView
android:layout_width="90dp"
android:layout_height="100dp"
android:id="#+id/teacher_item_picture"
style="#style/TeacherItemImage" />
<RatingBar
android:layout_width="80dp"
android:layout_height="wrap_content"
android:id="#+id/teacher_item_ratingbar"
style="#style/TeacherItemRatingBar" />
<TextView
android:id="#+id/teacher_item_name"
android:layout_width="180dp"
android:layout_height="16.5dp"
style="#style/TeacherItemName" />
<TextView
android:id="#+id/teacher_item_courses"
android:layout_width="180dp"
android:layout_height="33dp"
style="#style/TeacherItemCourses" />
<TextView
android:id="#+id/teacher_item_faculties"
android:layout_width="180dp"
android:layout_height="33dp"
style="#style/TeacherItemFaculties" />
</RelativeLayout>
recyclerview.xml
<RelativeLayout
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="wrap_content"
android:id="#+id/generic_listView"
android:layout_height="wrap_content"
style="#style/GenericListItem">
</android.support.v7.widget.RecyclerView>
</RelativeLayout>
teacherListFragment.javaimportant code
teacherListAdapter=new TeacherListAdapter(getActivity(),getData());
teacherListAdapter.setListener(this);
recyclerView.addItemDecoration(new RecyclerViewDivider(getActivity()));
recyclerView.setAdapter(teacherListAdapter);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
recyclerView.addOnItemTouchListener(new RecyclerViewClickListener(getActivity(), recyclerView, new RecyclerViewClickListener.OnItemClickListener() {
#Override
public void onItemClick(View view, int position) {
Log.d("D", view.getId() + "-" + position);
}
}));
getData() returns an List, this code is inside onCreateView
TeacherListAdatper
package wan.wanmarcos.views.adapters;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.text.Html;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.RatingBar;
import android.widget.TextView;
import android.widget.Toast;
import com.squareup.picasso.Picasso;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import wan.wanmarcos.R;
import wan.wanmarcos.managers.ItemAdapterListener;
import wan.wanmarcos.managers.ViewHolderSetters;
import wan.wanmarcos.models.Teacher;
import wan.wanmarcos.utils.Constants;
import wan.wanmarcos.views.widgets.CircleTransform;
public class TeacherListAdapter extends RecyclerView.Adapter<TeacherListAdapter.TeacherHolder> {
private LayoutInflater inflater;
private List<Teacher> teachers= Collections.emptyList();
private ItemAdapterListener itemAdapterListener;
public TeacherListAdapter(Context context,List<Teacher> teachers){
inflater= LayoutInflater.from(context);
this.teachers=teachers;
}
#Override
public TeacherHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view=inflater.inflate(Constants.TEACHER_NEW_ITEM, parent, false);
TeacherHolder teacherCustomer = new TeacherHolder(view);
return teacherCustomer;
}
#Override
public void onBindViewHolder(TeacherHolder holder, int position) {
Teacher teacher=teachers.get(position);
holder.setElements(teacher);
}
public void setListener(ItemAdapterListener listener){
this.itemAdapterListener =listener;
}
#Override
public int getItemCount() {
return teachers.size();
}
public class TeacherHolder extends RecyclerView.ViewHolder implements ViewHolderSetters<Teacher>,View.OnClickListener{
private TextView teacherName;
private RatingBar teacherRating;
private ImageView teacherImage;
private TextView teacherCourses;
private TextView teacherAssumptions;
private Teacher current;
public TeacherHolder(View itemView) {
super(itemView);
itemView.setOnClickListener(this);
teacherName= (TextView) itemView.findViewById(R.id.teacher_item_name);
teacherRating=(RatingBar)itemView.findViewById(R.id.teacher_item_ratingbar);
teacherImage=(ImageView)itemView.findViewById(R.id.teacher_item_picture);
teacherCourses=(TextView)itemView.findViewById(R.id.teacher_item_courses);
teacherAssumptions=(TextView)itemView.findViewById(R.id.teacher_item_faculties);
}
#Override
public void setElements(Teacher elements) {
current=elements;
teacherName.setText(elements.getName());
teacherRating.setRating(elements.getRaiting());
teacherCourses.setText(itemView.getResources().getString(R.string.teacher_capabilities)+ elements.getFaculties());
teacherAssumptions.setText(itemView.getResources().getString(R.string.teacher_ped) + elements.getDescription());
Picasso.with(itemView.getContext()).load(elements.getImageUrl()).transform(new CircleTransform()).into(teacherImage);
}
#Override
public void onClick(View v) {
//itemAdapterListener.itemClicked(v,current);
}
}
}
WHAT I WANT IS: why child items of my RecyclerVIew are the layouts containers?
I need someone to help me Thanks
Related
I am trying to implement a search bar for a social media app that displays users with a profile image at the right, the username and the full name aligned vertically next to the image and a follow button at the bottom right that only appears if the user is not following.
I am using a Firebase realtime database to pull data from and the username displays fine but the image and the full name are not displaying and the follow Button is not the right size, as you can see from the image below:
Wrong display
While I need to achieve this:
Correct display
Here is the xml for the user item that will populate the recycler view for the adapter:
<?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="wrap_content"
android:padding="8dp">
<de.hdodenhof.circleimageview.CircleImageView
android:id="#+id/image_profile"
android:layout_width="50dp"
android:layout_height="50dp"
android:src="#mipmap/ic_launcher"/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toEndOf="#id/image_profile"
android:layout_marginStart="5dp"
android:orientation="vertical"
android:layout_centerVertical="true">
<TextView
android:id="#+id/username"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="username"
android:maxLines="1"
android:textStyle="bold"
android:textColor="#color/black"/>
<TextView
android:id="#+id/fullname"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Full Name"
android:maxLines="1"/>
</LinearLayout>
<Button
android:id="#+id/btn_follow"
android:layout_width="wrap_content"
android:layout_height="30dp"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:visibility="gone"/>
</RelativeLayout>
Here the User Adapter:
package com.andrea.uncut.ui.Adapter;
import android.content.Context;
import android.content.SharedPreferences;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.fragment.app.FragmentActivity;
import androidx.recyclerview.widget.RecyclerView;
import com.andrea.uncut.R;
import com.andrea.uncut.ui.Model.User;
import com.andrea.uncut.ui.profile.ProfileFragment;
import com.bumptech.glide.Glide;
import com.google.firebase.auth.FirebaseAuth;
import com.google.firebase.auth.FirebaseUser;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
import java.util.List;
import de.hdodenhof.circleimageview.CircleImageView;
public class UserAdapter extends RecyclerView.Adapter<UserAdapter.ViewHolder>{
private Context mContext;
private List<User> mUsers;
private FirebaseUser firebaseUser;
public UserAdapter(Context mContext, List<User> mUsers) {
this.mContext = mContext;
this.mUsers = mUsers;
}
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(mContext).inflate(R.layout.user_item, parent, false);
return new UserAdapter.ViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
firebaseUser = FirebaseAuth.getInstance().getCurrentUser();
final User user = mUsers.get(position);
holder.btn_follow.setVisibility(View.VISIBLE);
holder.username.setText(user.getUsername());
holder.fullname.setText(user.getFullname());
Glide.with(mContext).load(user.getImageURL()).into(holder.image_profile);
isFollowing(user.getId(), holder.btn_follow);
if (user.getId().equals(firebaseUser.getUid())){
holder.btn_follow.setVisibility(View.GONE);
}
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
SharedPreferences.Editor editor = mContext.getSharedPreferences("PREFS", Context.MODE_PRIVATE).edit();
editor.putString("profileid", user.getId());
editor.apply();
((FragmentActivity)mContext).getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
new ProfileFragment()).commit();
}
});
holder.btn_follow.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (holder.btn_follow.getText().toString().equals("follow")){
FirebaseDatabase.getInstance().getReference().child("Follow").child(firebaseUser.getUid())
.child("following").child(user.getId()).setValue(true);
FirebaseDatabase.getInstance().getReference().child("Follow").child(user.getId())
.child("followers").child(firebaseUser.getUid()).setValue(true);
}else{
FirebaseDatabase.getInstance().getReference().child("Follow").child(firebaseUser.getUid())
.child("following").child(user.getId()).removeValue();
FirebaseDatabase.getInstance().getReference().child("Follow").child(user.getId())
.child("followers").child(firebaseUser.getUid()).removeValue();
}
}
});
}
#Override
public int getItemCount() {
return mUsers.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public TextView username;
public TextView fullname;
public CircleImageView image_profile;
public Button btn_follow;
public ViewHolder(#NonNull View itemView){
super(itemView);
username = itemView.findViewById(R.id.username);
fullname = itemView.findViewById(R.id.fullname);
image_profile = itemView.findViewById(R.id.image_profile);
btn_follow = itemView.findViewById(R.id.btn_follow);
}
}
private void isFollowing(String userid, Button button){
DatabaseReference reference = FirebaseDatabase.getInstance().getReference()
.child("Follow").child(firebaseUser.getUid()).child("following");
reference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
if (snapshot.child(userid).exists()){
button.setText("following");
}else{
button.setText("follow");
}
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
}
Thanks in advance for the help!
This could probably be due to wrap_content value for both the relative layout of user-item and button element.
So trying assigning fixed values to the layout and view.
Also, add font size and padding for the text in the button element to not look distorted or broken.
i'm just setup my RecyclerView but there's not appear in my emulator & there is error "E/RecyclerView: No adapter attached; skipping layout" Could you guys help me to find my failure?
This is my application layout :
Click here to see my application layout view
StockContent.Java (Fragment) :
package com.example.psmandroidapps;
import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.cardview.widget.CardView;
import androidx.core.graphics.drawable.RoundedBitmapDrawable;
import androidx.core.graphics.drawable.RoundedBitmapDrawableFactory;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.GradientDrawable;
import android.media.Image;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.Toast;
import android.widget.Toolbar;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List;
public class StockContent extends Fragment {
RecyclerView StockRecyclerView;
List<ModalClass> mList;
CustomAdapter customAdapter;
public StockContent() {
// Required empty public constructor
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View stockview = inflater.inflate(R.layout.stock_content, container, false);
StockRecyclerView = stockview.findViewById(R.id.StockRecyclerView);
customAdapter = new CustomAdapter(mList,getContext());
StockRecyclerView.setAdapter(customAdapter);
StockRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
return stockview;
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//just for sample only
mList = new ArrayList<>();
mList.add(new ModalClass(R.drawable.profilepicture,"Mitsubishi S-N50"));
mList.add(new ModalClass(R.drawable.logodetail,"Mitsubishi S-N50"));
mList.add(new ModalClass(R.drawable.logo,"Mitsubishi S-N50"));
mList.add(new ModalClass(R.drawable.profilepicture,"Mitsubishi S-N50"));
mList.add(new ModalClass(R.drawable.logodetail,"Mitsubishi S-N50"));
mList.add(new ModalClass(R.drawable.logo,"Mitsubishi S-N50"));
}
}
StockContent.XML :
<?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="#F3FFFC">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/StockRecyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
</androidx.recyclerview.widget.RecyclerView>
</LinearLayout>
Stock_CardView.XML (for recyclerview content) :
<?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="wrap_content"
android:layout_height="wrap_content">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardCornerRadius="15dp"
android:layout_margin="20dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<androidx.cardview.widget.CardView
android:layout_width="100dp"
android:layout_height="100dp"
app:cardCornerRadius="30dp"
android:layout_margin="15dp"
android:layout_weight="0.1">
<ImageView
android:id="#+id/img_goodspicture"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#drawable/profilepicture"
android:scaleType="centerCrop"/>
</androidx.cardview.widget.CardView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_weight="1"
android:layout_marginTop="10dp"
android:layout_marginRight="15dp"
>
<TextView
android:id="#+id/txt_goodsname"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Mitsubishi S-N10 (220V)"
android:textColor="#000000"
android:fontFamily="#font/sarabun_bold"
android:textSize="21dp"
android:layout_marginBottom="0dp"/>
<TextView
android:id="#+id/txt_goodstype"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Jenis : Contactor"
android:textColor="#000000"
android:fontFamily="#font/sarabun_regular"
android:textSize="12.5dp" />
<TextView
android:id="#+id/txt_goodsstock"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Stok : 105 pcs"
android:textColor="#000000"
android:fontFamily="#font/sarabun_regular"
android:textSize="12.5dp"/>
<TextView
android:id="#+id/txt_dateofgoodsentry"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Tanggal masuk : 29/07/2020"
android:textColor="#000000"
android:fontFamily="#font/sarabun_regular"
android:textSize="12.5dp"/>
</LinearLayout>
</LinearLayout>
</androidx.cardview.widget.CardView>
</LinearLayout>
ModalClass.Java :
package com.example.psmandroidapps;
public class ModalClass {
int image;
String text;
public ModalClass(int image, String text) {
this.image = image;
this.text = text;
}
public int getImage() {
return image;
}
public void setImage(int image) {
this.image = image;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
}
CustomAdapter.Java :
package com.example.psmandroidapps;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.MyViewHolder> {
List<ModalClass> mList;
Context context;
public CustomAdapter(List<ModalClass> mList, Context context) {
this.mList = mList;
this.context = context;
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(context);
View view = layoutInflater.inflate(R.layout.stock_cardview,parent,false);
return new MyViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull MyViewHolder holder, int position) {
holder.imageView.setImageResource(mList.get(position).getImage());
holder.textView.setText(mList.get(position).getText());
}
#Override
public int getItemCount() {
return mList.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder {
ImageView imageView;
TextView textView;
public MyViewHolder(#NonNull View itemView) {
super(itemView);
imageView=itemView.findViewById(R.id.img_goodspicture);
textView=itemView.findViewById(R.id.txt_goodsname);
}
}
}
Thats the code of mine.. the result is nothing, nothing showing in my emulator.. Thank you for read this question, hope you guys can help me to solve my problem here. Thank you guys! have a nice day
I'm trying to inflate a RecyclerView which has as StaggeredGrid Layout, but it is not showing anything. I've pretty much copied previous code I've used before for the RecyclerView so I'm kind of stumped.
In MuseumStoriesViewHolder.onCreateViewHolder() the return of holder has the following value ViewHolder{337ec22b position=-1 id=-1, oldPos=-1, pLpos:-1 unboundundefined adapter position no parent} I'm not sure if this is realated, but it was something that seemed off to me.
It also might help to know that the fragment I'm inflating this RecyclerView is a nested Fragment.
Any help would be greatly appreciated.
MuseumFragment
package com.example.android.radiobuttontestproject.fragments;
import android.app.Activity;
import android.os.Bundle;
import android.app.Fragment;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.example.android.radiobuttontestproject.R;
import com.example.android.radiobuttontestproject.adapters.MuseumStoriesAdapter;
import com.example.android.radiobuttontestproject.helpers.pojo.StoryObject;
import com.example.android.radiobuttontestproject.test.SampleDataFactory;
import java.util.List;
import butterknife.Bind;
import butterknife.ButterKnife;
public class MuseumFragment extends Fragment {
private List<StoryObject> storyObjectList;
private StaggeredGridLayoutManager storyGridLayoutManager;
private MuseumStoriesAdapter storyAdapter;
#Bind(R.id.stories_recycler_view) RecyclerView storiesRecyclerView;
public static MuseumFragment newInstance() {
MuseumFragment fragment = new MuseumFragment();
Bundle args = new Bundle();
fragment.setArguments(args);
return fragment;
}
public MuseumFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_museum, container, false);
ButterKnife.bind(this, view);
//Sets up the stories
SampleDataFactory sampleDataFactory = new SampleDataFactory();
storyObjectList = sampleDataFactory.getSampleStories(
getResources().getStringArray(R.array.test_titles_for_grid_museum1),
getResources().getStringArray(R.array.test_desc_for_grid_museum1));
storyGridLayoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
storiesRecyclerView.setLayoutManager(storyGridLayoutManager);
storyAdapter = new MuseumStoriesAdapter(getActivity().getApplicationContext(), storyObjectList);
storiesRecyclerView.setAdapter(storyAdapter);
return view;
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
}
#Override
public void onDetach() {
super.onDetach();
}
}
MuseumStoriesAdapter
package com.example.android.radiobuttontestproject.adapters;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;
import com.example.android.radiobuttontestproject.R;
import com.example.android.radiobuttontestproject.helpers.pojo.StoryObject;
import java.util.List;
public class MuseumStoriesAdapter extends RecyclerView.Adapter<MuseumStoriesAdapter.MuseumStoriesViewHolder> {
private List<StoryObject> itemList;
private LayoutInflater inflater;
private Context context;
public MuseumStoriesAdapter(Context context, List<StoryObject> itemList) {
this.itemList = itemList;
this.context = context;
inflater = LayoutInflater.from(this.context);
}
#Override
public MuseumStoriesViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
View view = inflater.inflate(R.layout.view_box_small, viewGroup, false);
MuseumStoriesViewHolder holder = new MuseumStoriesViewHolder(view);
return holder;
}
#Override
public void onBindViewHolder(MuseumStoriesViewHolder holder, int position) {
holder.title.setText(itemList.get(position).getTitle());
holder.desc.setText(itemList.get(position).getDescription());
}
#Override
public int getItemCount() {
return itemList.size();
}
class MuseumStoriesViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
public TextView type,title,desc;
public MuseumStoriesViewHolder(View itemView) {
super(itemView);
//Tried Butterknife, but it doesn't seem like it was working in the view holder. - Peter
type = (TextView) itemView.findViewById(R.id.small_box_type);
title = (TextView) itemView.findViewById(R.id.small_box_title);
desc = (TextView) itemView.findViewById(R.id.small_box_desc);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View view) {
Toast.makeText(view.getContext(), "Clicked Position = " + getPosition(), Toast.LENGTH_SHORT).show();
}
}
}
fragment_museum.xml
<ScrollView
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"
tools:context="com.example.android.radiobuttontestproject.fragments.MuseumFragment">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:weightSum="1">
<TextView
android:id="#+id/museum_header"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="#dimen/header_margin"
android:gravity="center"
android:textSize="#dimen/font_larger"
android:text="#string/museum_header" />
<android.support.v7.widget.RecyclerView
android:id="#+id/stories_recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</ScrollView>
view_box_small.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="#dimen/small_box_margin"
android:background="#color/small_box_background_color">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!--TODO Make layout_height wrap contenet -->
<ImageView
android:layout_width="match_parent"
android:layout_height="120dp"
android:background="#color/test_color2"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:src="#drawable/abc_btn_rating_star_off_mtrl_alpha"
/>
</FrameLayout>
<TextView
android:id="#+id/small_box_type"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="#dimen/font_small"
android:textColor="#color/font_red"
android:text="Object"
/>
<TextView
android:id="#+id/small_box_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="#dimen/font_large"
android:textColor="#color/font_black"
android:text="Sample Text Here"
/>
<TextView
android:id="#+id/small_box_desc"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="#dimen/font_normal"
android:textColor="#color/font_black"
android:textStyle="italic"
android:text="Sample Text Here"
/>
</LinearLayout>
I want to create a list where the listview will display a textview and an icon for each row. The diagram should be as follows:
Other than that, The data is retrieved from the database. The attribute of "favorite" will be checked first and if true, then the image in listview will be assigned with favorite_icon.png. Else, no icon need to be assigned.
I have been search for the related answer and tutorial, but all of them is too different from what I want and I cannot understand it very much. Hope somebody here can help me. Thank you in advance.
Here is what I got after I have done my Homework
First we set up a custom layout for listview and also for the row of the listview we will use later.
Here is the custom_listview_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/customListView" />
</LinearLayout>
Here is the custom_listview_row.xml
<?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:gravity="center_vertical"
android:minHeight="64dp">
<ImageView
android:id="#+id/clv_imageView"
android:layout_width="32dp"
android:layout_height="32dp"
android:contentDescription="#string/empty"
android:layout_alignParentRight="true"
android:layout_marginLeft="9dp"
android:layout_alignParentTop="true"/>
<TextView
android:id="#+id/clv_textView"
android:layout_width="97dp"
android:layout_height="32dp"
android:layout_alignParentLeft="true"
android:gravity="center_vertical"
android:text="#string/tv_definition"
android:textIsSelectable="true" />
</RelativeLayout>
Then we need to customized how our Custom ArrayAdaptor will look and do.
But before that, make sure you have put your icon in the drawable folder.
Here is my MyPerformanceArrayAdapter.java
import java.util.List;
import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
public class MyPerformanceArrayAdapter extends ArrayAdapter<DefinitionObject>{
private List<DefinitionObject> entries;
private Activity activity;
public MyPerformanceArrayAdapter(Activity a, int textViewResourceId, List<DefinitionObject> entries) {
super(a, textViewResourceId, entries);
this.entries = entries;
this.activity = a;
}
public static class ViewHolder{
public TextView item1;
public ImageView item2;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
ViewHolder holder;
if (v == null) {
LayoutInflater vi =
(LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.custom_listview_row, null);
holder = new ViewHolder();
holder.item1 = (TextView) v.findViewById(R.id.clv_textView);
holder.item2 = (ImageView) v.findViewById(R.id.clv_imageView);
v.setTag(holder);
}
else
holder=(ViewHolder)v.getTag();
final DefinitionObject custom = entries.get(position);
if (custom != null) {
holder.item1.setText(custom.getWord());
if(custom.getFav().equalsIgnoreCase("0"))
{
holder.item2.setImageResource(R.drawable.fav);
holder.item2.setVisibility(holder.item2.INVISIBLE);
}
else
{
holder.item2.setImageResource(R.drawable.fav2);
}
}
return v;
}
}
And lastly, here is my Activity to View the ListView using the CustomArrayAdaptor.
import java.util.List;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.ListView;
public class TempCLV extends Activity {
private MySQLiteDefinitionHelper db;
String tblName = "";
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.custom_listview_main);
Intent msjIntent = getIntent();
tblName = msjIntent.getStringExtra(WordDefinitionHomeActivity.TABLENAME2);
refresh();
}
public void refresh()
{
db = new MySQLiteDefinitionHelper(this);
final List<DefinitionObject> values = db.getAllWords(tblName);
ListView mylist = (ListView)findViewById(R.id.customListView);
MyPerformanceArrayAdapter adapter = new MyPerformanceArrayAdapter(this, R.id.customListView, values);
mylist.setAdapter(adapter);
}
}
Ok, my problem is similar to this Background image in ListView entries spontaneously disappearing
but this issue is resolved with using setImageResource on a normal ImageView but I want an animation to exist on all elements of a list, and this can not be done without a custom ImageView class that allows the animation to run. Does anyone know why these images are disappearing after scrolling in the list view and maybe how this can be fixed? Thanks a lot!
Here is my ListAdapter:
package com.mmgworldwide.layout.listadapters;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import com.mmgworldwide.R;
import com.mmgworldwide.customviews.SpinLoadingAnim;
import com.mmgworldwide.data.FWREvent;
import com.mmgworldwide.data.ImageThreadLoader;
import com.mmgworldwide.data.ImageThreadLoader.ImageLoadedListener;
import com.mmgworldwide.layout.ListDivider;
import com.mmgworldwide.data.Personality;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.Drawable;
import android.text.SpannableString;
import android.text.style.UnderlineSpan;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
public class PersonalityListAdapter extends ArrayAdapter<Object>{
private Context parentContext;
public ArrayList<Object> items_list_ref;
private ImageThreadLoader imageLoader = new ImageThreadLoader();
public PersonalityListAdapter(Context context, int resource, int textViewResourceId, ArrayList<Object> items_list) {
super(context, resource, textViewResourceId, items_list);
items_list_ref = items_list;
parentContext = context;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
Object node = (Object) items_list_ref.get(position);
LayoutInflater inflater = (LayoutInflater) parentContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if(node instanceof ListDivider){
//make new div bar
View div = inflater.inflate(R.layout.list_bar, parent, false);
TextView div_label = (TextView) div.findViewById(R.id.div_label);
div_label.setText(((ListDivider) node).label.toUpperCase());
return div;
}
View row = inflater.inflate(R.layout.picture_list, parent, false);
TextView name_txt = (TextView) row.findViewById(R.id.name_txt);
TextView title_txt = (TextView) row.findViewById(R.id.title_txt);
final ImageView portrait_img = (ImageView) row.findViewById(R.id.portrait);
final ImageView load_cnt = (ImageView) row.findViewById(R.id.portrait_loadDisplay);
name_txt.setText(((Personality) node).getName());
SpannableString title_underlined = new SpannableString(((Personality) node).getTitle());
title_underlined .setSpan(new UnderlineSpan(), 0, title_underlined.length(), 0);
title_txt.setText(title_underlined);
load_cnt.setVisibility(View.VISIBLE);
return row;
}
Here is my custom ImageView class
package com.mmgworldwide.customviews;
import android.R;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.AnimationDrawable;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.ImageView;
public class SpinLoadingAnim extends ImageView{
AnimationDrawable animation;
private final Integer FRAME_SPEED = 20;
public SpinLoadingAnim(Context context, AttributeSet attrs){
super(context, attrs);
//setBackgroundColor(Color.GREEN);
animation = new AnimationDrawable();
animation.addFrame(context.getResources().getDrawable(com.mmgworldwide.R.drawable.spinner_00000), FRAME_SPEED);
animation.addFrame(context.getResources().getDrawable(com.mmgworldwide.R.drawable.spinner_00001), FRAME_SPEED);
animation.addFrame(context.getResources().getDrawable(com.mmgworldwide.R.drawable.spinner_00002), FRAME_SPEED);
animation.addFrame(context.getResources().getDrawable(com.mmgworldwide.R.drawable.spinner_00003), FRAME_SPEED);
animation.setOneShot(false);
this.setBackgroundDrawable(animation);
this.post(new Starter());
}
class Starter implements Runnable {
public void run() {
animation.start();
}
}
And here is my layout XML
<?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="wrap_content"
android:background="#FFFFFF"
android:gravity="center_vertical"
android:paddingTop="10dp"
android:paddingBottom="10dp"
android:paddingLeft="10dp"
android:paddingRight="10dp">
<ImageView android:layout_width="60dp" android:layout_height="60dp" android:id="#+id/portrait" android:layout_centerVertical="true"></ImageView>
<com.mmgworldwide.customviews.SpinLoadingAnim
android:id="#+id/portrait_loadDisplay"
android:layout_width="20dp" android:layout_height="20dp"
android:background="#939598"
android:layout_centerVertical="true" android:layout_marginLeft="20dp"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true" />
<ImageView android:layout_height="wrap_content" android:layout_width="wrap_content" android:layout_centerVertical="true" android:id="#+id/arrow" android:src="#drawable/list_arrow" android:layout_alignParentRight="true"></ImageView>
<LinearLayout android:layout_toRightOf="#id/portrait" android:layout_toLeftOf="#id/arrow" android:layout_centerVertical="true" android:orientation="vertical" android:layout_height="wrap_content" android:layout_width="wrap_content" android:baselineAligned="true" android:paddingLeft="15dp" android:paddingRight="15dp">
<TextView android:text="CHEF NAME" android:id="#+id/name_txt" android:layout_width="wrap_content" android:textColor="#000000" android:textStyle="bold"
android:layout_height="wrap_content" android:paddingBottom="2dp" android:textSize="15sp"></TextView>
<TextView android:text="Chef Title" android:id="#+id/title_txt" android:layout_width="wrap_content" android:textColor="#000000"
android:layout_height="wrap_content" android:textSize="13sp"></TextView>
</LinearLayout>
</RelativeLayout>
Every 5th 'preloader' graphic is still disappearing, but thanks Michele this has helped a lot, and made things cleaner.
package com.mmgworldwide.layout;
import java.util.ArrayList;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import com.mmgworldwide.R;
import com.mmgworldwide.data.DataConnection;
import com.mmgworldwide.data.ImageThreadLoader;
import com.mmgworldwide.data.Personality;
//http://code.google.com/p/and-conference/source/browse/trunk/src/com/totsp/conference/PresentationList.java
public class Personalities extends Activity{
private ListView listView;
private ArrayAdapter<Object> adapter;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.personalities);
listView = (ListView) findViewById(R.id.personalitylistview);
listView.setDrawingCacheEnabled(false);
addListAdapter();
setFooterView("more");
}
private void addListAdapter(){
ArrayList<Object> adaptList = makeAdaptList();
adapter = new PersonalityListAdapter(this, 0, adaptList);
listView.setAdapter(adapter);
}
private ArrayList<Object> makeAdaptList(){
ArrayList<Object> adaptList = new ArrayList<Object>();
String currentDivDate = " ";
for(Personality aEvent : DataConnection.fwrInfo.getPersonalityList()){
adaptList.add(aEvent);
}
return adaptList;
}
private void setFooterView(String highlight){
Footer footer = (Footer) findViewById(R.id.footer);
footer.setHighlight(highlight);
}
//***********************************************************************************************************************************************
//ViewHolder
//***********************************************************************************************************************************************
static class ViewHolder {
private TextView tView1;
private TextView tView2;
private ImageView iView1;
}
//***********************************************************************************************************************************************
//PersonalityListAdapter
//***********************************************************************************************************************************************
private class PersonalityListAdapter extends ArrayAdapter<Object>{
LayoutInflater vi = (LayoutInflater) Personalities.this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
private Context parentContext;
public ArrayList<Object> items_list_ref;
private ImageThreadLoader imageLoader = new ImageThreadLoader();
public PersonalityListAdapter(final Context context, final int resId, final ArrayList<Object> presentations) {
super(context, resId, presentations);
this.items_list_ref = presentations;
parentContext = context;
}
#Override
public int getCount() {
return items_list_ref.size();
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
//Log.d("TROY", "adding view");
View v = convertView;
if (v == null) {
//Log.d("TROY", "inflation");
v = vi.inflate(R.layout.picture_list, parent, false);
ViewHolder viewHolder = new ViewHolder();
viewHolder.tView1 = (TextView) v.findViewById(R.id.name_txt);
viewHolder.tView2 = (TextView) v.findViewById(R.id.title_txt);
viewHolder.iView1 = (ImageView) v.findViewById(R.id.portrait);
v.setTag(viewHolder);
}
Object p = items_list_ref.get(position);
if (p != null) {
//Log.d("TROY", "setting stuff");
ViewHolder viewHolder = (ViewHolder) v.getTag();
viewHolder.tView1.setText("hi");
}
return v;
}
}
}
Here is a screen shot of what's going on (why is the 5th preload graphic not showing?):
edit ------
Ok, I added the getCount and getItemId overrides but still have the same issues, I figured I would start a project from scratch and try again with just a listView, same issue, I have put up a test project to demonstrate this frustrating issue. In this test I did not even add any data to the adapters, and the animation only works for some of them, just like with my master project.
Thank you so much for your patience and help this far Michele, you have been very awesome.
http://faceonfire.com/temp/ListTester.zip
ListViews are highly optimized Datastructures. You should use ViewHolders to obey the rules of Lists and make the life of the system a bit easier.
When you Scroll a ListView the System caches the Items in Holders for performance.
Read How to load the Listview "smoothly" in android
you can also try to set
yourListView.setDrawingCacheEnabled(false);
edit: ok than try to set your animation with xml
http://developer.android.com/reference/android/graphics/drawable/AnimationDrawable.html
like:
<!-- Animation frames are wheel0.png -- wheel5.png files inside the
res/drawable/ folder -->
<animation-list android:id="selected" android:oneshot="false">
<item android:drawable="#drawable/wheel0" android:duration="50" />
<item android:drawable="#drawable/wheel1" android:duration="50" />
<item android:drawable="#drawable/wheel2" android:duration="50" />
<item android:drawable="#drawable/wheel3" android:duration="50" />
<item android:drawable="#drawable/wheel4" android:duration="50" />
<item android:drawable="#drawable/wheel5" android:duration="50" />
</animation-list>
edit2: please try to implement getCount and getItemId, theres something wrong with the boundarys of your List, maybe android cant find out on with position the list is after scrolling. Oh and can you please test it with random data, not the same item all the way (perhaps some weird hash (default getItemId Implementation?) that is always the same with the same item content).
for example like this:
#Override
public int getCount() {
return <yourdatastructure>.getSize();
}
#Override
public long getItemId(int position) {
return position;
}