I want to display a carousel like an item in the RecyclerView. I use lib CarouselView.
MainActivity.java
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RecyclerView list = (RecyclerView) findViewById(R.id.list);
list.setHasFixedSize(true);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
list.setLayoutManager(layoutManager);
List<Integer> numbers = new ArrayList<>();
for (int i = 0; i < 10; i++) {
numbers.add(i);
}
final CarouselAdapter adapter = new CarouselAdapter(this, numbers);
list.setAdapter(adapter);
final SwipeRefreshLayout swipeRefresh = (SwipeRefreshLayout) findViewById(R.id.swipe_refresh);
swipeRefresh.setColorSchemeResources(R.color.green);
swipeRefresh.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
swipeRefresh.setRefreshing(false);
adapter.notifyDataSetChanged();
}
});
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/swipe_refresh"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="#+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/green"
android:scrollbars="vertical"/>
</android.support.v4.widget.SwipeRefreshLayout>
CarouselAdapter.java
public class CarouselAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private Context context;
private List<Integer> numbers;
public CarouselAdapter(Context context, List<Integer> numbers) {
this.context = context;
this.numbers= numbers;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_list, null);
return new CarouselViewHolder(view);
}
#Override
public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) {
((CarouselViewHolder) holder).carousel.setPageCount(numbers.size());
((CarouselViewHolder) holder).carousel.setViewListener(viewListener);
}
#Override
public int getItemCount() {
return numbers.size();
}
private ViewListener viewListener = new ViewListener() {
#Override
public View setViewForPosition(int position) {
TextView textView = (TextView) LayoutInflater.from(context).inflate(R.layout.item_carousel, null);
textView.setText(String.valueOf(numbers.get(position)));
return textView;
}
};
private class CarouselViewHolder extends RecyclerView.ViewHolder {
public CarouselView carousel;
private CarouselViewHolder(View itemView) {
super(itemView);
carousel = (CarouselView) itemView.findViewById(R.id.carousel);
}
}
}
item_list.xml
<?xml version="1.0" encoding="utf-8"?>
<com.synnapps.carouselview.CarouselView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/carousel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:fillColor="#color/green"/>
item_carousel.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="16sp"/>
I change CarouselViewPager from CarouselView, added next code
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int height = 0;
if (getChildCount() != 0) {
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
child.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
int h = child.getMeasuredHeight();
if (h > height) height = h;
}
} else {
height = heightMeasureSpec;
}
heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
But when call swipe refresh and adapter update, all views in carousel disappear. I think that the problem is not called onMeasure after adapter.notifyDataSetChanged(). How I can fix it?
Related
I want to create a RecyclerView in Android which contains ViewHolders, that change their width and height as shown in the GIF below. I tried several LayoutManagers for the RecyclerView but I did not manage to get the result I wished for.
The RecyclerView should be a 1 dimensional row.
Hi you can use this to animate the views inside your RecyclerView as shown on the GIF below:
My adapter:
public class StringAdapter extends RecyclerView.Adapter<StringAdapter.StringHolder> {
private int defaultWidth = 0;
private int defaultHeight = 0;
private static final String[] strings = new String[]{"Item 1", "Item 2", "Item 3", "Item 4", "Item 5", "Item 6", "Item 7", "Item 8", "Item 8", "Item 10"};
private int lastSelected = -1;
private final RecyclerView.LayoutManager layoutManager;
private static final int animValue = 50;
StringAdapter(RecyclerView.LayoutManager layoutManager) {
this.layoutManager = layoutManager;
}
#NonNull
#Override
public StringHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.test_holder, parent, false);
return new StringHolder(v);
}
#Override
public void onBindViewHolder(#NonNull StringHolder holder, int position) {
holder.categories.setText(strings[position]);
ViewGroup.LayoutParams param = holder.card.getLayoutParams();
if (position == lastSelected) {
param.width = defaultWidth + animValue;
param.height = defaultHeight + animValue;
} else {
if (defaultWidth != 0 && defaultHeight != 0) {
param.width = defaultWidth;
param.height = defaultHeight;
}
}
}
#Override
public int getItemCount() {
return strings.length;
}
protected class StringHolder extends RecyclerView.ViewHolder {
private final TextView categories;
private final CardView card;
public StringHolder(#NonNull View itemView) {
super(itemView);
categories = itemView.findViewById(R.id.categories);
card = itemView.findViewById(R.id.cardCategories);
card.setOnClickListener(v -> {
int currentPosition = this.getAbsoluteAdapterPosition();
selection(currentPosition, lastSelected);
lastSelected = currentPosition;
});
}
private void selection(int newPosition, int oldPosition) {
if (newPosition != oldPosition) {
ConstraintLayout newView = (ConstraintLayout) layoutManager.findViewByPosition(newPosition);
ConstraintLayout oldView = (ConstraintLayout) layoutManager.findViewByPosition(oldPosition);
if (newView != null) {
defaultWidth = card.getWidth();
defaultHeight = card.getHeight();
selectAnimate(newView.getChildAt(0));
}
if (oldView != null) {
deselectAnimate(oldView.getChildAt(0));
} else {
notifyItemChanged(oldPosition);
}
}
}
private void selectAnimate(View view) {
ValueAnimator select = ValueAnimator.ofInt(defaultWidth, defaultWidth + animValue);
select.setInterpolator(new AccelerateDecelerateInterpolator());
select.setDuration(300);
select.start();
select.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator animation) {
ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
layoutParams.width = (int) animation.getAnimatedValue();
layoutParams.height = (int) (animation.getAnimatedValue()) + defaultHeight - defaultWidth;
view.requestLayout();
}
});
}
private void deselectAnimate(View view) {
ValueAnimator select = ValueAnimator.ofInt(defaultWidth + animValue, defaultWidth);
select.setInterpolator(new AccelerateDecelerateInterpolator());
select.setDuration(300);
select.start();
select.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator animation) {
ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
layoutParams.width = (int) animation.getAnimatedValue();
layoutParams.height = (int) (animation.getAnimatedValue()) + defaultHeight - defaultWidth;
view.requestLayout();
}
});
}
}
}
My MainActivity :
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RecyclerView recyclerView = findViewById(R.id.recyclerView);
LinearLayoutManager layoutManager = new LinearLayoutManager(this, RecyclerView.HORIZONTAL, false);
recyclerView.setLayoutManager(layoutManager);
StringAdapter adapter = new StringAdapter(layoutManager);
recyclerView.setAdapter(adapter);
}
}
My MainActivity Layout
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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_width="match_parent"
android:layout_height="match_parent"
tools:context=".test.MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="300dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
And finaly this MyHolder Layout :
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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="match_parent"
android:layout_marginStart="5dp">
<androidx.cardview.widget.CardView
android:id="#+id/cardCategories"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:cardCornerRadius="15dp"
app:cardUseCompatPadding="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent">
<TextView
android:id="#+id/categories"
android:layout_width="wrap_content"
android:layout_height="35dp"
android:layout_gravity="center"
android:gravity="center"
android:paddingStart="10dp"
android:paddingEnd="10dp"
android:text="Some Text"
android:textSize="16sp" />
</androidx.cardview.widget.CardView>
</androidx.constraintlayout.widget.ConstraintLayout>
I'm creating a calendar app, with each month being displayed using a RecylcerView. Inside each day of each month, there is another RecyclerView to display events on that day. I'm using the custuomLinearLayoutManager from https://stackoverflow.com/a/38513905/13199395, and I've looked at many examples. My code for the nesting is very similar to them but for some reason is not working. Any help as to why is not working would be much appreciated.
The month view:
<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_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MonthViewActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/calView"
android:layout_width="match_parent"
android:layout_height="581dp"
android:layout_gravity="bottom" />
</FrameLayout>
The view for each day:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/dayView"
android:layout_width="145px"
android:layout_height="265px"
android:orientation="vertical">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/eventDayView"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</androidx.recyclerview.widget.RecyclerView>
</LinearLayout>
and the view for the inner recyclerView:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/showEvents"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="#+id/eventName"
android:layout_width="145px"
android:layout_height="wrap_content" />
</LinearLayout>
The adapter for the main recyclerview:
public class MonthViewAdapter extends RecyclerView.Adapter<MonthViewAdapter.ViewHolder> {
Context context;
ArrayList<Day> days;
CustomLinearLayoutManager l;
public MonthViewAdapter(Context context, ArrayList<Day> arrayList) {
this.context = context;
this.days = arrayList;
}
#NonNull
#Override
public MonthViewAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.content_events, parent, false);
return new ViewHolder(view, this.mOnDayClickListener);
}
#Override
public void onBindViewHolder(MonthViewAdapter.ViewHolder holder, int position) {
l = new CustomLinearLayoutManager(context, LinearLayout.VERTICAL, false);
ViewGroup.LayoutParams params=holder.r.getLayoutParams();
params.height=100;
holder.r.setLayoutParams(params);
holder.r.setLayoutManager(l);
EventViewAdapter adapter = new EventViewAdapter(context, days.get(position).getEvents(), this.mOnDayClickListener);
holder.r.setAdapter(adapter);
holder.t.setText(days.get(position).getMonthDayNumber());
}
#Override
public int getItemCount() {
return days.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
RecyclerView r;
TextView t;
FrameLayout f;
LinearLayout l;
public ViewHolder(View itemView) {
super(itemView);
l = itemView.findViewById(R.id.dayView);
t = itemView.findViewById(R.id.dayNum);
r = itemView.findViewById(R.id.eventDayView);
}
}
}
The adapter for the inner RecyclerView:
public class EventViewAdapter extends RecyclerView.Adapter<EventViewAdapter.ViewHolder> {
Context context;
ArrayList<Event> events;
public EventViewAdapter (Context context, ArrayList<Event> arrayList) {
this.context = context;
this.events = arrayList;
}
#Override
public EventViewAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.content_single_event, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(EventViewAdapter.ViewHolder holder, int position) {
Log.d("event", Integer.toString(events.size()));
holder.eventName.setText(events.get(position).getName());
}
#Override
public int getItemCount() {
return events.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView eventName;
LinearLayout linearLayout;
public ViewHolder(View itemView) {
super(itemView);
eventName = itemView.findViewById(R.id.eventName);
linearLayout = itemView.findViewById(R.id.showEvents);
}
}
}
The custom linear layout manager: https://stackoverflow.com/a/38513905/13199395
And the activity
public class MonthViewActivity extends AppCompatActivity{
RecyclerView month;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_month_view);
month.setHasFixedSize(true);
month.addItemDecoration(new DividerItemDecoration(this,
DividerItemDecoration.HORIZONTAL));
month.addItemDecoration(new DividerItemDecoration(this,
DividerItemDecoration.VERTICAL));
GridLayoutManager g = new GridLayoutManager(this, 7);
month.setLayoutManager(g);
ArrayList<Day> day = new ArrayList<>();
LocalDate dd = LocalDate.now();
Day d1 = new Day(dd);
Day d2 = new Day(dd.plusDays(1));
Day d3 = new Day(dd.plusDays(2));
d1.addEvent(new Event("a"));
day.add(d1);
adapter = new MonthViewAdapter(this, day, this);
month.setAdapter(adapter);
}
}
Each element of the list that I pass into the month view adapter has a list of events that are then passed into the event adapter. However, each day in the grid only shows one of the events, it does not show all of the events in the event list on each day. Why is this happening and how can I fix it? I am getting an error (java.lang.IndexOutOfBoundsException: Invalid item position) on
View view = recycler.getViewForPosition(position);
in the custom layout manager, but the program does not crash.
Hey I'm doing filtering data on my project using bottom Sheet with view-pager and two fragments i can pass data from activity to view-pager adapter and get in fragment through constructor but how can i get data from fragment to activity using bottom-sheet
this is how i send data from activity
adapter = new PagerAdapters(this.getSupportFragmentManager(),
tabLayout.getTabCount(),_id);
and receive data with constructor in fragment
public Filterfragment(String _id) {
this._id = _id;
}
And I'm using recyclerview to show data like this
So how can i send id of the item to activity so i can reload my recyclerview data when the apply button click.
<?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="match_parent"
android:id="#+id/bottom_sheet"
android:background="#android:color/white"
app:behavior_peekHeight="0dp"
app:layout_behavior="android.support.design.widget.BottomSheetBehavior"
android:orientation="vertical">
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
app:tabGravity="fill"
app:tabMode="fixed"
app:tabPadding="0dp"/>
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_below="#id/tabs"
android:layout_above="#id/applyBtn"
android:layout_height="match_parent"
/>
<Button
android:id="#+id/applyBtn"
android:layout_width="match_parent"
android:text="Apply"
android:layout_alignParentBottom="true"
android:layout_height="wrap_content" />
</RelativeLayout>
This is main recyclerview adapter
public class FilterAdapter extends RecyclerView.Adapter<FilterAdapter.FilterViewHolder> {
private static final String TAG = "FilterAdapter";
Context context;
List<TagTypeResult> tagTypeModels;
public static int current_pos = -1;
TagAdapter tagAdapter;
int rotationAngle = 0;
public FilterAdapter(Context context, List<TagTypeResult> tagTypeModels) {
this.context = context;
this.tagTypeModels = tagTypeModels;
}
#NonNull
#Override
public FilterViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int i) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.filter_row_item,parent,false);
return new FilterAdapter.FilterViewHolder(v);
}
#Override
public void onBindViewHolder(#NonNull FilterViewHolder filterViewHolder, int i) {
TagTypeResult tagTypeModel = tagTypeModels.get(i);
filterViewHolder.txt.setText(tagTypeModel.getName());
filterViewHolder.sub_list_recycler.setVisibility(View.GONE);
if (tagTypeModel.getTagsLists() != null) {
if (tagTypeModel.getTagsLists().size() <= 0) {
filterViewHolder.arrow.setVisibility(View.GONE);
filterViewHolder.arrow.setRotationX(180);
} else {
filterViewHolder.arrow.setVisibility(View.VISIBLE);
filterViewHolder.arrow.setRotationX(0);
}
}else {
filterViewHolder.arrow.setVisibility(View.GONE);
}
tagAdapter = new TagAdapter(context, tagTypeModel.getTagsLists(), new TagInterface() {
#Override
public void tagClick(View view, int pos, String tagID) {
Log.d(TAG, "tagClick: "+tagID);
}
});
filterViewHolder.sub_list_recycler.setAdapter(tagAdapter);
tagAdapter.notifyDataSetChanged();
if (current_pos == filterViewHolder.getAdapterPosition()){
if (filterViewHolder.sub_list_recycler.getVisibility() == View.GONE) {
filterViewHolder.sub_list_recycler.setVisibility(View.VISIBLE);
}else {
filterViewHolder.sub_list_recycler.setVisibility(View.GONE);
}
}else {
Log.i(TAG, "onBindViewHolder: sublist gone "+tagTypeModel.getName());
filterViewHolder.sub_list_recycler.setVisibility(View.GONE);
}
}
#Override
public int getItemCount() {
return tagTypeModels.size();
}
class FilterViewHolder extends RecyclerView.ViewHolder {
TextView txt;
ImageView arrow;
RecyclerView sub_list_recycler;
RelativeLayout linearLayout;
FilterViewHolder(#NonNull View itemView) {
super(itemView);
txt = itemView.findViewById(R.id.txt);
arrow = itemView.findViewById(R.id.arrow);
linearLayout = itemView.findViewById(R.id.main_cat_lay);
linearLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.i(TAG, "onClick: "+current_pos);
if (current_pos != getAdapterPosition()) {
current_pos = getAdapterPosition();
notifyDataSetChanged();
}
else{
current_pos = -1;
notifyDataSetChanged();
}
}
});
sub_list_recycler = itemView.findViewById(R.id.sub_list_recycler);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(context) {
#Override
public boolean canScrollVertically() {
return false;
}
};
sub_list_recycler.setLayoutManager(mLayoutManager);
sub_list_recycler.addItemDecoration(new SimpleDividerItemDecoration(context));
}
}
}
sub recyclerView adapter :
public class TagAdapter extends RecyclerView.Adapter<TagAdapter.TagViewHolder> {
private static final String TAG = "SublistAdapter";
Context context;
List<TagsList> tagsLists;
int pos = -1;
TagInterface tagInterface;
public TagAdapter(Context context, List<TagsList> tagsLists,TagInterface tagInterface) {
this.context = context;
this.tagsLists = tagsLists;
this.tagInterface = tagInterface;
}
#NonNull
#Override
public TagViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int i) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.tag_item,parent,false);
return new TagAdapter.TagViewHolder(v);
}
#Override
public void onBindViewHolder(#NonNull TagViewHolder tagViewHolder, int i) {
TagsList tagsList = tagsLists.get(i);
tagViewHolder.tagtxt.setText(tagsList.getName());
if (tagsList.isChecked()){
tagViewHolder.tagName.setChecked(true);
}else {
tagViewHolder.tagName.setChecked(false);
}
}
#Override
public int getItemCount() {
return tagsLists.size();
}
public class TagViewHolder extends RecyclerView.ViewHolder {
TextView tagtxt;
CheckBox tagName;
RelativeLayout childClik;
public TagViewHolder(#NonNull View itemView) {
super(itemView);
//pri_txt = itemView.findViewById(R.id.pri_txt);
tagName = itemView.findViewById(R.id.tagName);
tagtxt = itemView.findViewById(R.id.tagtxt);
childClik = itemView.findViewById(R.id.childClik);
tagName.setEnabled(false);
childClik.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
boolean isChecked = true;
if (isChecked)
{
tagsLists.get(getAdapterPosition()).setChecked(true);
tagName.setChecked(true);
tagInterface.tagClick(v,getAdapterPosition(),tagsLists.get(getAdapterPosition()).get_id());
Toast.makeText(context, "[pos]"+tagsLists.get(getAdapterPosition()).get_id(), Toast.LENGTH_SHORT).show();
}else
{
tagsLists.get(getAdapterPosition()).setChecked(false);
tagName.setChecked(false);
}
}
});
}
}
}
I am looking at creating dynamic heights in my RecyclerView to be responsive across all devices. Currently this works fine but for the first two rows at the start I have a double cell and the height of these two rows gets set to the first cell. I want instead this cell on both the first and second row to match the height of the last cell and become a rectangle. I have tried a few ways but none seem to work I am not sure where the problem is but I hope someone can show me. I will attach screenshots and the code below.
SquareLayout.java
public class SquareLayout extends LinearLayout {
public SquareLayout(Context context) {
super(context);
}
public SquareLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SquareLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
protected void onMeasure(int width, int height) {
// int width = MeasureSpec.getSize(widthMeasureSpec);
//int height = MeasureSpec.getSize(heightMeasureSpec);
// note we are applying the width value as the height
//if(width>=370){
// super.onMeasure(widthMeasureSpec, widthMeasureSpec/2);
// }
// else{
// super.onMeasure(widthMeasureSpec, widthMeasureSpec);
// }
super.onMeasure(width, width);
// Log.d("int","int is: "+ width);
}
}
DataAdapter.java
public class DataAdapter extends RecyclerView.Adapter<DataAdapter.ViewHolder> {
private ArrayList<AndroidVersion> android;
private Context context;
public DataAdapter(Context context,ArrayList<AndroidVersion> android) {
this.android = android;
this.context = context;
}
#Override
public DataAdapter.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.row_layout, viewGroup, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(DataAdapter.ViewHolder viewHolder, int i) {
// int width = viewHolder.tv_android.getMeasuredWidth() / 2; //returns -1
Log.d("MYINT", "value: " + i);
//Picasso.with(context).load(android.get(i).getAndroid_image_url()).resize(240, 120).into(viewHolder.img_android);
}
#Override
public int getItemCount() {
return android.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
private LinearLayout testheight;
private ImageView img_android;
public ViewHolder(View view) {
super(view);
}
}
}
MainActivity.java
public class MainActivity extends AppCompatActivity {
private final String android_version_names[] = {
"test1",
"test2",
"test3",
"test4",
"test5",
"test6",
"test7",
"test8",
"test9",
"test10"
};
private final String android_image_urls[] = {
"http://example.com/images/test.png",
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initViews();
}
private void initViews(){
RecyclerView recyclerView = (RecyclerView)findViewById(R.id.card_recycler_view);
recyclerView.setHasFixedSize(true);
RecyclerView.LayoutManager mLayoutManager = new GridLayoutManager(getApplicationContext(),3);
ArrayList<AndroidVersion> androidVersions = prepareData();
((GridLayoutManager) mLayoutManager).setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
#Override
public int getSpanSize(int position) {
if (position == 0 || position == 2) {
return 2; // ITEMS AT POSITION 1 AND 6 OCCUPY 3 SPACES
}
else {
return 1; // OTHER ITEMS OCCUPY ONLY A SINGLE SPACE
}
}
});
recyclerView.setLayoutManager(mLayoutManager);
DataAdapter adapter = new DataAdapter(getApplicationContext(), androidVersions);
recyclerView.setAdapter(adapter);
}
private ArrayList<AndroidVersion> prepareData(){
ArrayList<AndroidVersion> android_version = new ArrayList<>();
for(int i=0;i<android_version_names.length;i++){
AndroidVersion androidVersion = new AndroidVersion();
androidVersion.setAndroid_version_name(android_version_names[i]);
androidVersion.setAndroid_image_url(android_image_urls[i]);
android_version.add(androidVersion);
}
return android_version;
}
}
row_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<example.SquareLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:background="#android:color/transparent"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginBottom="10dp"
android:layout_marginStart="10dp"
android:background="#color/reloadedpurple"
android:elevation="6dp"
android:orientation="vertical">
<ImageView
android:id="#+id/img_android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true" />
<TextView
android:id="#+id/tv_android"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center"
android:textColor="#FFFFFF"
android:textStyle="bold" />
</LinearLayout>
</example.SquareLayout>
I am developing an android app, where I am trying to implement one feature for Image gallary. Now, initially, I want to show some image url with their title name. I am using hashmap for mapping title with their image.I have the model class with two String fields url and title. But The problem is I am very new in the development field and now sure how to show the title based on image click. Here is my model Class
public class ImageModel implements Parcelable {
String name, url;
public ImageModel() {
}
protected ImageModel(Parcel in) {
name = in.readString();
url = in.readString();
}
public static final Creator<ImageModel> CREATOR = new Creator<ImageModel>() {
#Override
public ImageModel createFromParcel(Parcel in) {
return new ImageModel(in);
}
#Override
public ImageModel[] newArray(int size) {
return new ImageModel[size];
}
};
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeString(url);
}
}
Now the Main activity where I create a Hashmap with image and title to show those into views.
public class MainActivity extends AppCompatActivity {
GalleryAdapter mAdapter;
RecyclerView mRecyclerView;
ArrayList<ImageModel> data = new ArrayList<>();
ArrayList<HashMap<String, String>> arrayList = new ArrayList<>();
HashMap<String, String> h1 = new HashMap<>();
String[] imgUrls = {"https://images.unsplash.com/photo-1444090542259-0af8fa96557e?q=80&fm=jpg&w=1080&fit=max&s=4b703b77b42e067f949d14581f35019b",
"https://images.unsplash.com/photo-1439546743462-802cabef8e97?dpr=2&fit=crop&fm=jpg&h=725&q=50&w=1300",
"https://images.unsplash.com/photo-1441155472722-d17942a2b76a?q=80&fm=jpg&w=1080&fit=max&s=80cb5dbcf01265bb81c5e8380e4f5cc1"};
String[] imgNames = {"name1","name2","name3"};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
for (int i = 0; i < 3; i++) { //change size according to your size.
ImageModel imageModel = new ImageModel();
imageModel.setName(imgNames[i]);
imageModel.setUrl(imgUrls[i]);
data.add(imageModel);
}
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mRecyclerView = (RecyclerView) findViewById(R.id.list);
mRecyclerView.setLayoutManager(new GridLayoutManager(this, 3));
mRecyclerView.setHasFixedSize(true);
mAdapter = new GalleryAdapter(MainActivity.this, data);
mRecyclerView.setAdapter(mAdapter);
mRecyclerView.addOnItemTouchListener(new RecyclerItemClickListener(this,
new RecyclerItemClickListener.OnItemClickListener() {
#Override
public void onItemClick(View view, int position) {
Intent intent = new Intent(MainActivity.this, DetailActivity.class);
intent.putParcelableArrayListExtra("data", data);
intent.putExtra("pos", position);
startActivity(intent);
}
}));
}
}
GalleryAdapterCode
public class GalleryAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
Context context;
List<ImageModel> data = new ArrayList<>();
public GalleryAdapter(Context context, List<ImageModel> data) {
this.context = context;
this.data = data;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
RecyclerView.ViewHolder viewHolder;
View v;
v = LayoutInflater.from(parent.getContext()).inflate(
R.layout.list_item, parent, false);
viewHolder = new MyItemHolder(v);
return viewHolder;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
Glide.with(context).load(data.get(position).getUrl())
.thumbnail(0.5f)
.override(200,200)
.crossFade()
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(((MyItemHolder) holder).mImg);
((MyItemHolder) holder).mTextView.setText(data.get(position).getName());
}
#Override
public int getItemCount() {
return data.size();
}
public static class MyItemHolder extends RecyclerView.ViewHolder {
ImageView mImg;
TextView mTextView;
public MyItemHolder(View itemView) {
super(itemView);
mTextView = (TextView) itemView.findViewById(R.id.textView);
mImg = (ImageView) itemView.findViewById(R.id.item_img);
}
}
}
My XML Class for item list row is
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:weightSum="1">
<ImageView
android:id="#+id/item_img"
android:layout_width="match_parent"
android:layout_height="188dp"
android:adjustViewBounds="true"
android:background="#color/colorAccent"
android:contentDescription="#string/app_name"
android:scaleType="centerCrop"
android:src="#drawable/placeholder" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#7000"
android:orientation="vertical"
android:padding="10dp"
android:layout_alignBottom="#+id/item_img"
android:layout_alignParentStart="true">
<TextView
android:id="#+id/textView"
android:text="Headline"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#FFF"
android:textSize="15dp"
android:textStyle="normal|bold"
/>
</LinearLayout>
</RelativeLayout>
Create two String arrays one containing image urls and other names in MainActivity.
String[] imgUrls = {"url1","url2","url3"};
String[] imgNames = {"name1","name2","name3"};
Iterate over those arrays and create a list of the model class.
ArrayList<ImageModel> data = new ArrayList<ImageModel>();
for (int i = 0; i < 3; i++) { //change size according to your size.
ImageModel imageModel = new ImageModel();
imageModel.setName(imgNames[i]);
imageModel.setUrl(imgUrls[i]);
data.add(imageModel);
}
mAdapter = new GalleryAdapter(MainActivity.this, data);
mRecyclerView.setAdapter(mAdapter);
Add a TextView in your RecyclerView row layout R.layout.list_item.
In your adapter use this TextView to set name of image.
public static class MyItemHolder extends RecyclerView.ViewHolder {
ImageView mImg;
TextView mTextView;
public MyItemHolder(View itemView) {
super(itemView);
mTextView = (TextView) itemView.findViewById(R.id.item_textview);
mImg = (ImageView) itemView.findViewById(R.id.item_img);
}
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
Glide.with(context).load(data.get(position).getUrl())
.thumbnail(0.5f)
.override(200,200)
.crossFade()
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(((MyItemHolder) holder).mImg);
holder.mTextView.setText(data.get(position).getName());
}
Rest of your code will be the same.