Differentiate items from array list in recycle view adapter - android

I want to display feed like Instagram i am using 2 layouts for that.
Using Recycle view in that adapter i check with view type for multi image or single image, for multi image i am using view pager .
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view;
switch (viewType) {
case ModelUser.VIEW_PAGER:
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.feed_multi_photo, parent, false);
return new TextTypeViewHolder(view);
case ModelUser.IMAGE_TYPE:
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.feed_photo, parent, false);
return new ImageTypeViewHolder(view);
}
return null;
}
#Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int listPosition) {
ModelUser object = dataSet.get(listPosition);
if (object != null) {
switch (object.type1) {
case ModelUser.VIEW_PAGER:
final SliderPagerAdapter sliderPagerAdapter = new SliderPagerAdapter((Activity) mContext, slider_image_list);
((TextTypeViewHolder) holder).mvViewPager.setAdapter(sliderPagerAdapter);
((TextTypeViewHolder) holder).mvViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
addBottomDots(position, ((TextTypeViewHolder) holder).ll_dots);
page = position;
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
On setting adapter data i am using
MultiViewTypeAdapter feedMainAdapter = new MultiViewTypeAdapter(feed_list,imagelist,context);
RecylerFeed.setAdapter(feedMainAdapter);
feed_list is for single image and imagelist is for multiimage so,my problem is in imagelist i am getting list of every images how can i differentiate those images for particular user?

my problem is in imagelist i am getting list of every images
Because, passing slider_image_list in SliderPagerAdapter which contains all user images.
how can i differentiate those images for particular user?
Create new user specific image list from slider_image_list before passing to ViewPager:
case ModelUser.VIEW_PAGER:
//Create new List of images for current user from `slider_image_list`
ArrayList<> currentUserImages=new ArrayList<>();
final SliderPagerAdapter sliderPagerAdapter =
new SliderPagerAdapter((Activity) mContext, currentUserImages);
....
break;

Add RecyclereView in
feed_multi_photo
And inside onBindViewHolder
switch (object.type1) {
case ModelUser.VIEW_PAGER:
//Impement Nested RecyclerAdapter of Multiple Image using imagelist
InnerRecyclerviewAdapter adapter=new InnerRecyclerviewAdapter(context,imagelist);
holder.recyclerView.setAdapter(adapter);
holder.recyclerView.setHasFixedSize(true);
LinearLayoutManager layoutManager = new LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false);
recyclerView.setLayoutManager(layoutManager);

Related

How to change the background color of a textview inside recyclerview xamarin android

It is basically a recyclerview that I fill with some textviews to show some categories. I have access to the position of clicked item within recyclerview, but how can I get a reference to the actual textview to set the background color?
here is my code
RecyclerView CategoriesRecyclerView;
RecyclerView.LayoutManager CategoriesLayoutManager;
CategoriesAdapter CategoriesAdapter;
List<Category> categories;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
// Get our RecyclerView layout:
CategoriesRecyclerView = FindViewById<RecyclerView>(Resource.Id.CategoriesRecyclerView);
//............................................................
// Layout Manager Setup:
// Use the built-in linear layout manager:
CategoriesLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.Horizontal, true);
// Plug the layout manager into the RecyclerView:
CategoriesRecyclerView.SetLayoutManager(CategoriesLayoutManager);
//............................................................
// Adapter Setup:
CategoriesAdapter = new CategoriesAdapter(categories);
// Register the item click handler (below) with the adapter:
CategoriesAdapter.ItemClick += CategoriesOnItemClick;
// Plug the adapter into the RecyclerView:
CategoriesRecyclerView.SetAdapter(CategoriesAdapter);
}
void CategoriesOnItemClick(object sender, int position)
{
//here I want the reference to the textview
// ((TextView).SetBackgroundColor(Color.Aqua);
Toast.MakeText(this, "This is category " + categories[position].Id + categories[position].Name, ToastLength.Short).Show();
}
I found the answer to my question in case it would help someone. you use OnBindViewHolder method of the RecyclerView.Adapter and make a reference list of all the textviews. and then use the position to get the one clicked.
// ADAPTER
// Adapter to connect the data set to the RecyclerView:
public class CategoriesAdapter : RecyclerView.Adapter
{
// Event handler for item clicks:
public event EventHandler<int> ItemClick;
// Underlying data set
public List<Category> Categories;
public List<TextView> TextViews = new List<TextView>();
// Load the adapter with the data set at construction time:
public CategoriesAdapter(List<Category> categories)
{
this.Categories = categories;
}
// Create a new CardView (invoked by the layout manager):
public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
{
// Inflate the CardView for the photo:
View itemView = LayoutInflater.From(parent.Context).
Inflate(Resource.Layout.CategoryTextView, parent, false);
// Create a ViewHolder to find and hold these view references, and
// register OnClick with the view holder:
CategoryViewHolder vh = new CategoryViewHolder(itemView, OnClick);
return vh;
}
// Fill in the contents (invoked by the layout manager):
public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
var vh = holder as CategoryViewHolder;
vh.CategoryTextView.Text = Categories[position].Name;
TextViews.Add(vh.CategoryTextView);
if (position == 0)
{
vh.CategoryTextView.SetBackgroundColor(Color.Aqua);
}
vh.CategoryTextView.Click += (sender, e) =>
{
foreach (var textView in TextViews)
{
textView.SetBackgroundColor(Color.White);
}
((TextView)sender).SetBackgroundColor(Color.Aqua);
};
}
// Return the number of photos available in the photo album:
public override int ItemCount
{
get { return Categories.Count; }
}
// Raise an event when the item-click takes place:
void OnClick(int position)
{
if (ItemClick != null)
ItemClick(this, position);
}
}

How to load cardview GridView with Animations in Android?

I have created android app like gallery which have some images using gridview fragment.
Functionality of my application is working fine and image showing in fragment gridview and also my second activity open when i click on item but i want to show cardview GridView with Animations.
Also if it is easier default image in place of loading images instead of progress bar will be fine.
Here is my application fragment code :
public class CallFragment extends Fragment {
GridView grid;
String[] plan = {
"Student Bundle",
"SMS Plus Bundle",
"Instagram",
"Facebook",
"Flickr"
} ;
String[] web = {
"*3000",
"*106*1",
"Instagram",
"Facebook",
"Flickr"
} ;
int[] imageId = {
R.drawable.calla,
R.drawable.smsb,
R.drawable.person7,
R.drawable.person7,
R.drawable.person7
};
int[] fullimg = {
R.drawable.callaa,
R.drawable.smsbb,
R.drawable.person7,
R.drawable.person7,
R.drawable.person7
};
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
setHasOptionsMenu(true);
View view = inflater.inflate(R.layout.fragment_call,container,false);
CustomGrid adapter = new CustomGrid(getActivity(), plan, web, imageId, fullimg);
grid=(GridView) view.findViewById(R.id.grid);
grid.setAdapter(adapter);
grid.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
String value=(String)grid.getItemAtPosition(i);
Intent intent=new Intent(getActivity(),Book.class);
intent.putExtra("web", web[i]);
intent.putExtra("plan", plan[i]);
intent.putExtra("imageId", imageId[i]);
intent.putExtra("fullimg", fullimg[i]);
startActivity(intent);
}
});
return view;
}
Here is my application CustomAdapter code :
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.MyViewHolder> {
ArrayList<String> personNames;
ArrayList<String> personCode;
ArrayList<Integer> personImages;
ArrayList<Integer> personImages1;
Context context;
public CustomAdapter(Context context, ArrayList<String> personNames, ArrayList<String> personCode, ArrayList<Integer> personImages, ArrayList<Integer> personImages1) {
this.context = context;
this.personCode = personCode;
this.personNames = personNames;
this.personImages = personImages;
this.personImages1 = personImages1;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
// infalte the item Layout
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.rowlayout, parent, false);
// set the view's size, margins, paddings and layout parameters
MyViewHolder vh = new MyViewHolder(v); // pass the view to View Holder
return vh;
}
#Override
public void onBindViewHolder(MyViewHolder holder, final int position) {
// set the data in items
//holder.name.setText(personNames.get(position));
holder.image.setImageResource(personImages.get(position));
//holder.image.setImageResource(personImages1.get(position));
// implement setOnClickListener event on item view.
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// open another activity on item click
Intent intent = new Intent(context, SecondActivity.class);
//intent.putExtra("image", personImages.get(position)); // put image data in Intent
intent.putExtra("name", personNames.get(position)); // put image data in Intent
intent.putExtra("code", personCode.get(position)); // put image data in Intent
intent.putExtra("image", personImages1.get(position)); // put image data in Intent
context.startActivity(intent); // start Intent
}
});
}
#Override
public int getItemCount() {
return personNames.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder {
// init the item view's
TextView name;
TextView code;
ImageView image;
public MyViewHolder(View itemView) {
super(itemView);
// get the reference of item view's
name = (TextView) itemView.findViewById(R.id.name);
code = (TextView) itemView.findViewById(R.id.code);
image = (ImageView) itemView.findViewById(R.id.image);
}
}
}
Here is example of my requirement :
My gridview looks like this :
Create an separate XML file under anim and apply in the onBindViewHolder.
#Override
public void onBindViewHolder(ViewHolder holder, int position)
{
// Here you apply the animation when the view is bound
setAnimation(holder.itemView, position);
}
/**
* Here is the key method to apply the animation
*/
private void setAnimation(View viewToAnimate, int position)
{. int lastPosition=0;
// If the bound view wasn't previously displayed on screen, it's animated
if (position > lastPosition)
{
Animation animation = AnimationUtils.loadAnimation(context, android.R.anim.slide_in_left);
viewToAnimate.startAnimation(animation);
lastPosition = position;
}
}
}
You can apply animations on RecyclerView using this tutorial.
and for default image just put a src property inside your imageview in R.layout.rowlayout XML file
Used this Recyclerview with Load animation
Recyclerview Load Animation

How to implement single selection in RecyclerView?

I can change properties of selected item in RecyclerView but I want to remove selection for older selections.
Here is how I create RecyclerView :
fragmentViewPagerAdapter.addFragmentView((arg1, arg2, arg3) -> {
View view = arg1.inflate(R.layout.recyclerview_layout, arg2, false);
RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.recyclerView);
selectDateRecyclerViewAdapter = new SelectDateRecyclerViewAdapter(dayList,this,(v,position) ->
{
AppCompatButton appCompatButton = (AppCompatButton)v.findViewById(R.id.selectHourButton);
AppCompatImageView appCompatImageView = (AppCompatImageView)v.findViewById(R.id.calendarDot);
highlightButton(appCompatButton,appCompatImageView);
});
recyclerView.setHasFixedSize(false);
recyclerView.addItemDecoration(selectDateRecyclerViewAdapter. new CalendarItemDecoration(10,dayList.size()));
GridLayoutManager gridLayoutManager = new GridLayoutManager(getApplicationContext(),4,GridLayoutManager.VERTICAL,false);
recyclerView.setLayoutManager(gridLayoutManager);
recyclerView.setAdapter(selectDateRecyclerViewAdapter);
selectDateRecyclerViewAdapter.notifyDataSetChanged();
return view;
});
highlightButton method changes background of Button etc.
Thanks.
You may need to hold flags to record which buttons are selected, when you select a new item, clear the flags first and reset it to the position of your new selected item. Then notifyDataSetChanged() or notifyItemChanged().done.
The main code of this function may be placed in highlightButton method. so It's better If you post the highlightButton code.
Since its a single selection, you can track the selected position using an external variable, say int selectedIndex;
In your adapter code :
public class ViewHolder extends RecyclerView.ViewHolder {
View itemView;
public ViewHolder(View v) {
super(v);
itemView = v;
v.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
selectedPostion = getAdapterPosition();
if( selectedPosition == RecyclerView.NO_POSITION) return;
recyclerViewOnItemClickListener.onItemSelect(itemView, getAdapterPosition()); //Custom listener - in turn calls your highlightButton method
//call notifyDataSetChanged(); or notifyItemRangeChanged();
}
});
}
}
#Override
public void onBindViewHolder(ViewHolder holder, final int position) {
holder.itemView.setSelected(position == selectedPostion);
}

Nested ArrayList while creating RecyclerView

I am developing an android application where i am using a RecyclerView to display a list of items.I am getting the list from server as json.So my problem is within this list i am getting another list as item.That is if my main arraylist contain title and materials, the material is another arraylist.So can you please suggest a solution to display a list within recyclerview.
The code below is my adapter
public class CurriculumAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private Context mContext;
private ArrayList<Curriculum> mArrayListCurriculum;
public CurriculumAdapter(Context mContext, ArrayList<Curriculum> mArrayListCurriculum) {
this.mContext = mContext;
this.mArrayListCurriculum = mArrayListCurriculum;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.adapter_key_features, parent,false);
return new KeyFeatureViewHolder(v);
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
if (holder instanceof KeyFeatureViewHolder) {
((KeyFeatureViewHolder) holder).mTextViewFeatureTitle.setText(mArrayListCurriculum.get(position).getTitle());
}
}
#Override
public int getItemCount() {
return mArrayListCurriculum == null ? 0 : mArrayListCurriculum.size();
}
public static class KeyFeatureViewHolder extends RecyclerView.ViewHolder {
public TextView mTextViewFeatureTitle;
public KeyFeatureViewHolder(View itemView) {
super(itemView);
mTextViewFeatureTitle = (TextView) itemView.findViewById(R.id.txtFeature);
}
}
}
The code below is my fragment with dummy arraylist data
public class CourseCurriculumFragment extends Fragment {
private FragmentInterface mFragmentInterface;
private ArrayList<Curriculum> mArrayListCurriculum;
private ArrayList<Material> mArrayListMaterial;
private RecyclerView mRecyclerViewCurriculum;
private LinearLayoutManager mLinearLayoutManager;
private CurriculumAdapter mCurriculumAdapter;
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_course_curriculum, container, false);
return view;
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
initView(view);
}
private void initView(View view) {
mArrayListMaterial = new ArrayList<>();
mArrayListCurriculum = new ArrayList<>();
populateMaterials();
populateKeyFeatures();
mRecyclerViewCurriculum = (RecyclerView) view.findViewById(R.id.recyclerViewCurriculum);
mCurriculumAdapter = new CurriculumAdapter(getActivity(), mArrayListCurriculum);
mLinearLayoutManager = new LinearLayoutManager(getActivity());
mRecyclerViewCurriculum.setLayoutManager(mLinearLayoutManager);
mRecyclerViewCurriculum.setAdapter(mCurriculumAdapter);
mRecyclerViewCurriculum.setItemAnimator(new DefaultItemAnimator());
}
private void populateMaterials() {
mArrayListMaterial.add(new Material("12:00","pdf","","Sample Text","0"));
mArrayListMaterial.add(new Material("12:00","pdf","","Sample Text","0"));
}
private void populateKeyFeatures() {
mArrayListCurriculum.add(new Curriculum("UNIT 1",mArrayListMaterial));
mArrayListCurriculum.add(new Curriculum("UNIT 2",mArrayListMaterial));
mArrayListCurriculum.add(new Curriculum("UNIT 3",mArrayListMaterial));
}
}
A bind method in a holder is a good way to pass data to it.
In your case this bind method should take in a Curriculum and a Material object as parameters.
Inside the onBindViewHolder method of the adapter, instead of reaching into the variables of the holder, you should call this bind method.
In the implementation of the method inside the you KeyFeatureViewHolder class you should use these passed parameters and display them in the appropriate UI elements.
Lastly, to get the Material object data into adapter, add ArrayList<Material> as a constructor parameter just like you did with Curriculum.
Use RecyclerView with header, title as header and materials as items of that header. Look at this example.
You need to design a custom list for yourself. For example take an object like this.
public class ListItem {
public curriculumName = null;
public materialName = null;
}
Now populate this list after you parse the JSON string. Get your first Curriculum and populate the object like this
private ArrayList<ListItem> mListItemArray = new ArrayList<ListItem> ();
for(curriculum : mArrayListCurriculum) {
ListItem mListItemHead = new ListItem();
mListItemHead.curriculumName = curriculum.getName();
// Set the header here
mListItemArray.add(mListItemHead);
for(material : curriculum.getMaterials()){
ListItem mListItem = new ListItem();
mListItem.materialName = material.getName();
// Add materials here
mListItemArray.add(mListItem);
}
}
Now, you've a list with headers and materials. When the materialName in your mListItemArray is null, it identifies that this is a header and vice versa.
Now the trick is to modify your adapter of your RecyclerView so that you can bind proper view to your items in your list.
You can find an indication from this answer on how you can achieve this desired behaviour.
Basically, the idea is to modify your getItemViewType to pass the proper view in your onBindViewHolder. Your getItemViewType might look like this.
#Override
public int getItemViewType(int position) {
if (mListItemArray.get(position).curriculumName != null) {
// This is where we'll add header.
return HEADER_VIEW;
}
return super.getItemViewType(position);
}

how to update Listview while at the end of Listview scrolling in Android?

I'm trying to display the listview from sqlite. At the end of Listview I want to load next 10 data from sqlite and this process will continue till data ends in SQLite. But the issue is data load at first time successfully and when i scroll 3rd time page/data does not load and after LocalListPageIndex= 2 then progress bar is continuously running.
Here is my Code of ListView Scrolling.
listView.removeFooterView(progressBar);
listView.setOnScrollListener(new AbsListView.OnScrollListener() {
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
#Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, final int totalItemCount) {
lastInScreen = firstVisibleItem + visibleItemCount;
if (X != firstVisibleItem) {
if (LocalListPageIndex <= 5) {
Toast.makeText(getApplicationContext(), "Your Last Item." + lastInScreen, Toast.LENGTH_SHORT).show();
if (lastInScreen == totalItemCount) {
listView.addFooterView(progressBar);
// Execute some code after 15 seconds have passed
Handler handler = new Handler();
handler.postDelayed(new Runnable()
{
public void run()
{
LocalListPageIndex += 1;
int OFFSET_SCROLL = 10
List<All_Post> allDesc = dbhelper.getAllDescriptions(OFFSET_SCROLL);
for (All_Post all_Post : allDesc) {
descArray.add(all_Post);
}
if (adapter != null) {
adapter.notifyDataSetChanged();
// adapter = new AllPostAdapter(getApplicationContext(), R.layout.allpostlist, descArray);
listView.setAdapter(adapter);
//listView.invalidateViews();
listView.setSelection(totalItemCount);
}
}
}, 15000);
}
} if (LocalListPageIndex == 5) {
Log.e("hide footer", "footer hide");
listView.removeFooterView(progressBar);
}
}
X = firstVisibleItem;
}
});
You could try using RecyclerView:
The RecyclerView widget is a more advanced and flexible version of ListView. This widget is a container for displaying large data sets that can be scrolled very efficiently by maintaining a limited number of views. Use the RecyclerViewwidget when you have data collections whose elements change at runtime based on user action or network events.
A layout manager positions item views inside a RecyclerView and determines when to reuse item views that are no longer visible to the user. To reuse (or recycle) a view, a layout manager may ask the adapter to replace the contents of the view with a different element from the dataset. Recycling views in this manner improves performance by avoiding the creation of unnecessary views or performing expensivefindViewById() lookups
Example:
Add this view to your layout:
android.support.v7.widget.RecyclerView
android:id="#+id/my_recycler_view"
android:scrollbars="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
Once you have added a RecyclerView widget to your layout, obtain a handle to the object, connect it to a layout manager, and attach an adapter for the data to be displayed:
public class MyActivity extends Activity {
private RecyclerView mRecyclerView;
private RecyclerView.Adapter mAdapter;
private RecyclerView.LayoutManager mLayoutManager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_activity);
mRecyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
// use this setting to improve performance if you know that changes
// in content do not change the layout size of the RecyclerView
mRecyclerView.setHasFixedSize(true);
// use a linear layout manager
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
// specify an adapter (see also next example)
// Set your myDataSet with the url of your images.
mAdapter = new MyAdapter(myDataset);
mRecyclerView.setAdapter(mAdapter);
}
...
}
Create an adapter to manage the recycler view:
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
private MySQLClass 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 ViewHolder extends RecyclerView.ViewHolder {
// each data item is just a string in this case
public ViewHolder(TextView v) {
super(v);
textView = v;
}
}
// Provide a suitable constructor (depends on the kind of dataset)
public MyAdapter(MySQLClass myDataset) {
mDataset = myDataset;
}
// Create new views (invoked by the layout manager)
#Override
public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
// create a new view
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.my_image_view, parent, false);
// set the view's size, margins, paddings and layout parameters
...
ViewHolder vh = new ViewHolder(v);
return vh;
}
// Replace the contents of a view (invoked by the layout manager)
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
textView.setText(mDataset.get(i));
}
// Return the size of your dataset (invoked by the layout manager)
#Override
public int getItemCount() {
return mDataset.length;
}
}
info from:
http://developer.android.com/training/material/lists-cards.html
When you are working with retrieving the data from the database its better to use loaders.A loader will load all the details depending upon your query and give it to you in the form of a Cursor.Now you can simply give that cursor to CursorAdapter(if you are using Cursor adapter)or you can extract the data from cursor to a list and give that list to normal adapter.

Categories

Resources