Android RecyclerView Blank Space - android

I have an android project and I am using Recycler view to print a list with items, each item has just one image and between those images, android is creating a big blank space. I researched and saw about to change my layout to wrap_content and I changed it the recycler view layout, the itemlayout, the layout of the page but didn't work, I want to know what more options do I have to change, I will post here my 2 classes, the activity, and the adapter, and both layout XML and the item XML (Recycler viewItem )
ACTIVITY:
public class MenuPrincipal extends AppCompatActivity {
private RecyclerView recyclerView;
private MenuEsportesAdapter adapterGrupos;
private ArrayList<MenuEsporte> listaGruposMenu;
private ImageView imgTopo;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_menu_principal);
imgTopo = (ImageView) findViewById(R.id.MenuPrincipal_imagemTopo);
imgTopo.setImageResource(R.drawable.sol);
MenuEsporte me = new MenuEsporte();
listaGruposMenu = me.getAllEsportes();
recyclerView = (RecyclerView) findViewById(R.id.recyclerViewMenuGrupo);
recyclerView.setLayoutManager(new GridLayoutManager(this, 2));
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setHasFixedSize(false);
adapterGrupos = new MenuEsportesAdapter(this, listaGruposMenu, onClickGruposMenu());
recyclerView.setAdapter(adapterGrupos);
}
private MenuEsportesAdapter.MenuEsporteOnClickListener onClickGruposMenu(){
return new MenuEsportesAdapter.MenuEsporteOnClickListener(){
#Override
public void onClickMenuEsporte(MenuEsportesAdapter.MenuEsportesViewHolder holder, int idx) {
Toast.makeText(getApplicationContext(),"Clicou " + idx, Toast.LENGTH_SHORT).show();
Intent i = new Intent(getApplicationContext(),JogosClassificacao.class);
Bundle bundle = new Bundle();
bundle.putString("Esporte", listaGruposMenu.get(idx).nomeEsporte);
i.putExtras(bundle);
startActivity(i);
}
};
}
}
ADAPTER
public class MenuEsportesAdapter extends RecyclerView.Adapter<MenuEsportesAdapter.MenuEsportesViewHolder> {
protected static final String TAG = "livroandroid";
private final List<MenuEsporte> listaMenuEsporte;
private final Context context;
private final MenuEsporteOnClickListener onClickListener;
public interface MenuEsporteOnClickListener {
public void onClickMenuEsporte(MenuEsportesViewHolder holder, int idx);
}
public MenuEsportesAdapter(Context context, List<MenuEsporte> listaMenuEsporte, MenuEsporteOnClickListener onClickListener) {
this.context = context;
this.listaMenuEsporte = listaMenuEsporte;
this.onClickListener = onClickListener;
}
#Override
public MenuEsportesViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
// Este método cria uma subclasse de RecyclerView.ViewHolder
// Infla a view do layout
View view = LayoutInflater.from(context).inflate(R.layout.lista_item, viewGroup, false);
// Cria a classe do ViewHolder
MenuEsportesViewHolder holder = new MenuEsportesViewHolder(view);
return holder;
}
#Override
public void onBindViewHolder(final MenuEsportesViewHolder holder, final int position) {
// Este método recebe o índice do elemento, e atualiza as views que estão dentro do ViewHolder
MenuEsporte c = listaMenuEsporte.get(position);
// Atualizada os valores nas views
//holder.tNome.setText(c.nomeEsporte);
holder.img.setImageResource(c.fotoResource);
//holder.img.setImageURI(Uri.fromFile(file));
// Click
if (onClickListener != null) {
holder.itemView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Chama o listener para informar que clicou no Planeta
onClickListener.onClickMenuEsporte(holder, position);
}
});
}
}
#Override
public int getItemCount() {
return this.listaMenuEsporte != null ? this.listaMenuEsporte.size() : 0;
}
// Subclasse de RecyclerView.ViewHolder. Contém todas as views.
public static class MenuEsportesViewHolder extends RecyclerView.ViewHolder {
public TextView tNome;
ImageView img;
private View view;
public MenuEsportesViewHolder(View view) {
super(view);
this.view = view;
// Cria as views para salvar no ViewHolder
//tNome = (TextView) view.findViewById(R.id.textViewNome);
img = (ImageView) view.findViewById(R.id.imageViewFoto);
}
}
}
And the xmls
<?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">
<!--
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textColor="#000000"
android:id="#+id/textViewNome"/>
-->
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/imageViewFoto"/>
</LinearLayout>
Second:
<?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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context="juriteam.br.com.thr_sportgames.paginas.MenuPrincipal"
tools:showIn="#layout/activity_menu_principal"
android:orientation="vertical">
<ImageView
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="2"
android:id="#+id/MenuPrincipal_imagemTopo"
android:layout_gravity="center_horizontal" />
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerViewMenuGrupo"
android:layout_height="0dp"
android:layout_weight="7"
android:layout_width="match_parent"/>
</LinearLayout>
Can someone please help me ?
Sorry about the names and comments in portuguese. Any question please ask me.
Thank you so much

Problem is with RecyclerView item layout. You have given match_parent property to ImageView. Instead of this give constant size like 48dp.

In the lista_item layout, you should set the height to wrap_content or a constant size.

You have to specify the height of your ImageView in your lista_item instead of setting the height to match_parent

Related

How to save spanCount of RecyclerView on Shared Preferences?

my question is is there a way to save the SpamCount of a ReciclerView in SharedPreferences?
I try to make a List that can change the view from a "List mode" to "Grid mode" and save that information in SharedPreferences so that the "List View" will remain after killing the app.
The example of what I am trying to do would be the following ...
example of what i try to do on button click
And the code that I try to change is the following ...
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private static RecyclerView recyclerView;
private ReciclerAdapter reciclerAdapter;
ImageView viewGridS, viewListS;
SharedPreferences vSettings;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.recicler_main);
vSettings = this.getSharedPreferences("Vision", 0);
notesRecyclerView = findViewById(R.id.recycler_view);
notesRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(1, StaggeredGridLayoutManager.VERTICAL));
viewListS = findViewById(R.id.viewList);
viewGridS = findViewById(R.id.viewGrid);
#Override
public void onClick(View v) {
SharedPreferences vSettings = this.getSharedPreferences("Vision", 0);
SharedPreferences.Editor viEdit = vSettings.edit();
switch (v.getId())
{
case R.id.viewList:
viewGridS.setVisibility(View.GONE);
viewListS.setVisibility(View.VISIBLE);
viEdit.putString("Vision",listView());
viEdit.apply();
break;
case R.id.viewGrid:
viewListS.setVisibility(View.GONE);
viewGridS.setVisibility(View.VISIBLE);
listWiew();
viEdit.putString("Vision",gridView());
viEdit.apply();
break;
}
});
}
public int gridView(){
notesRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL));
return null;
}
public int listView(){
notesRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(1,StaggeredGridLayoutManager.VERTICAL));
return null;
}
}
When trying to start the Activity the RecyclerView does not show anything and the button does not work.
if someone could help me I would appreciate it in advance ... thanks
You have done couple of things wrong here.
Incorrect use of SharedPreferences
Adapter on RecycleView not setup
Manage LinearLayout and StaggeredGridLayoutManager
I will try to accomplished kind similar end result which you are looking for, a simple button which is switching layout on click. Code as follows -
MainActivity.java
public class MainActivity extends AppCompatActivity {
private String LIST_VIEW = "List View";
private String GRID_VIEW = "Grid View";
private RecyclerView recyclerView;
private LinearLayoutManager linearLayoutManager;
private StaggeredGridLayoutManager staggeredGridLayoutManager;
private SharedPreferences sharedPreferences;
private RecycleViewAdapter recycleViewAdapter;
#Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Simple List setup for data to show in recycle view
List<String> stringList = new ArrayList<>();
stringList.add("Monday\nI'll ask her out.");
stringList.add("Tuesday");
stringList.add("Wednesday\nI'll take her to garden to talk.");
stringList.add("Thursday\nI'll give her a gift");
stringList.add("Friday");
stringList.add("Saturday");
stringList.add("Sunday\nI'll propose her. ");
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
recyclerView = findViewById(R.id.recycler_view);
recycleViewAdapter = new RecycleViewAdapter(this, stringList);
linearLayoutManager = new LinearLayoutManager(this);
linearLayoutManager.setOrientation(RecyclerView.VERTICAL);
staggeredGridLayoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
/*
* SharedPreferences value will be null for very first install of app
* ELSE SharedPreferences will have use last saved value
* */
String CURRENT_VIEW = sharedPreferences.getString("LAYOUT_TYPE", null);
if (CURRENT_VIEW == null) {
CURRENT_VIEW = LIST_VIEW;
sharedPreferences.edit().putString("LAYOUT_TYPE", LIST_VIEW).apply();
recyclerView.setLayoutManager(linearLayoutManager);
recyclerView.setAdapter(recycleViewAdapter);
} else
switchView(CURRENT_VIEW);
Button buttonPanel = findViewById(R.id.buttonPanel);
buttonPanel.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(sharedPreferences.getString("LAYOUT_TYPE", null).equals(LIST_VIEW))
switchView(GRID_VIEW);
else
switchView(LIST_VIEW);
}
});
}
/*
* Method will switch Layout on RecycleView and update new Adapter
* #param: Required Layout Type (LIST_VIEW or GRID_VIEW)
* */
private void switchView(String layoutTypeValue) {
if (layoutTypeValue.equals(LIST_VIEW))
recyclerView.setLayoutManager(linearLayoutManager);
else if (layoutTypeValue.equals(GRID_VIEW))
recyclerView.setLayoutManager(staggeredGridLayoutManager);
sharedPreferences.edit().putString("LAYOUT_TYPE", layoutTypeValue).apply();
recyclerView.setAdapter(recycleViewAdapter);
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<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"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<Button
android:padding="8dp"
android:layout_margin="16dp"
android:layout_gravity="end|bottom"
android:id="#+id/buttonPanel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#android:color/white"
android:background="#android:color/holo_orange_dark"
android:text="Change Layout"/>
</FrameLayout>
RecycleViewAdapter.java
public class RecycleViewAdapter extends RecyclerView.Adapter<RecycleViewAdapter.CustomViewHolder> {
private Context context;
private List<String> stringList;
public RecycleViewAdapter(Context context, List<String> stringList) {
this.context = context;
this.stringList = stringList;
}
#NonNull
#Override
public CustomViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
return new CustomViewHolder(LayoutInflater.from(context).inflate(R.layout.recycle_item_layout, parent, false));
}
#Override
public void onBindViewHolder(#NonNull CustomViewHolder holder, int position) {
holder.textView.setText(stringList.get(position));
}
#Override
public int getItemCount() {
return stringList.size();
}
public class CustomViewHolder extends RecyclerView.ViewHolder {
private TextView textView;
public CustomViewHolder(#NonNull View itemView) {
super(itemView);
textView = itemView.findViewById(R.id.text);
}
}
}
recycle_item_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_margin="8dp">
<TextView
android:id="#+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp"
android:background="#android:color/holo_blue_dark"
android:textColor="#android:color/white"
android:textSize="24sp" />
</LinearLayout>
Above code will give you following result -
Happy Coding !

Create curved layout for Android Wearable Recycler View

I am trying to create a curved Wearable Recycler view similar to the one given in below link: https://developer.android.com/training/wearables/ui/lists.html
But I don't see curved layout and all the text comes in a single line .
Can anyone help me how to create a curved Wearable Recycler view . The below is the code fragment. Please let me know if something went wrong in the below code:
My Layout is below:
<?xml version="1.0" encoding="utf-8"?>
<android.support.wearable.view.WearableRecyclerView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/menu_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
>
</android.support.wearable.view.WearableRecyclerView>
In my fragment I am using the below code for curved layout:
InformationAdapter informationAdapter = new InformationAdapter(dataSet, images,MenuActivity.this );<br>
wearableRecyclerView.setAdapter(informationAdapter); <br>
wearableRecyclerView.setCenterEdgeItems(true);<br>
wearableRecyclerView.setLayoutManager(new CurvedChildLayoutManager(getActivity()));<br>
wearableRecyclerView.setCircularScrollingGestureEnabled(true);
wearableRecyclerView.setBezelWidth(0.5f);
wearableRecyclerView.setScrollDegreesPerScreen(90);
My Adapter is as below:
public class InformationAdapter extends
WearableRecyclerView.Adapter<InformationAdapter.ViewHolder> {
private static final String TAG = "CustomRecyclerAdapter";
private String[] mDataSet;
private int[] mImages;
private ItemClickListener itemClickListener;
// Custom Controller used to instruct main activity to update {#link Notification} and/or
// UI for item selected.
public static class ViewHolder extends WearableRecyclerView.ViewHolder {
private final TextView mTextView;
private final ImageView menuImageIcon;
public ViewHolder(View view) {
super(view);
mTextView = (TextView) view.findViewById(R.id.textView);
menuImageIcon = (ImageView)view.findViewById(R.id.menu_image);
}
#Override
public String toString() { return (String) mTextView.getText(); }
}
public InformationAdapter(String[] dataSet,int[] mImages,ItemClickListener itemClickListener) {
mDataSet = dataSet;
this.mImages = mImages;
this.itemClickListener = itemClickListener;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
View view = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.recycler_row_item, viewGroup, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(ViewHolder viewHolder, final int position) {
Log.d(TAG, "Element " + position + " set.");
viewHolder.mTextView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// mController.itemSelected(mDataSet[position]);
itemClickListener.onItemSelected(mDataSet[position]);
}
});
// Replaces content of view with correct element from data set
viewHolder.mTextView.setText(mDataSet[position]);
viewHolder.menuImageIcon.setImageResource(mImages[position]);
}
// Return the size of your dataset (invoked by the layout manager)
#Override
public int getItemCount() {
return mDataSet.length;
}
}
Row Item layout for Adapter:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:paddingTop="#dimen/recycler_row_padding"
android:orientation="horizontal">
<ImageView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:src="#drawable/ic_n_white_48dp"
android:id="#+id/menu_image"/>
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:textSize="#dimen/recycler_row_text_size"
android:id="#+id/textView"
/>
</LinearLayout>
I faced with the same problem. Changing
android:layout_height="wrap_content"
to
android:layout_height="match_parent"
in WearableRecyclerView worked for me. Hope it helps.

How to make two Recyclerview in one Layout

i already success to make one Recyclerview and i want to add new Recyclerview Horizontal on top. i will explain in my code :
<android.support.v7.widget.RecyclerView
android:id="#+id/arrayListUser"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:divider="#color/white">
</android.support.v7.widget.RecyclerView>
<android.support.v7.widget.RecyclerView
android:id="#+id/arrayList"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:divider="#color/white">
</android.support.v7.widget.RecyclerView>
id:arrayList is my first Recyclerview have name xml feeds_listview
id:arrayListUser is my new Recyclerview, i want make this Recyclerview Horizontal
xml for new Recylerview is feeds_listviewUser
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<de.hdodenhof.circleimageview.CircleImageView
android:id="#+id/profil"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginBottom="5dp"
android:layout_marginTop="30dp"
android:layout_gravity="center"
android:src="#drawable/cthprofil" />
<TextView
android:id="#+id/fullName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:layout_marginTop="5dp"
android:layout_marginBottom="20"
android:text="Megi Fernanda"
android:textSize="17sp"
android:textColor="#color/colordefault"
android:textStyle="bold" />
</LinearLayout>
and this is my class adapter
public class FeedsCustomAdapter extends RecyclerView.Adapter<FeedsCustomAdapter.ViewHolder> {
private Context context;
private List<FeedsAdapter> feeds_list;
private ArrayList<Feeds> mFeedsList = new ArrayList<Feeds>();
private OnItemClickListener mListener;
private OnItemClickListener mListener2;
public FeedsCustomAdapter(Context context, ArrayList<Feeds> mFeedsList) {
this.context = context;
this.mFeedsList = mFeedsList;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.feeds_listview, parent, false);
return new ViewHolder(itemView);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
Feeds feed = getFeeds().get(position);
int textColor = context.getResources().getColor(R.color.btn_next);
int textColor2 = context.getResources().getColor(R.color.text_color_black);
holder.fullName.setText(feed.user.fullName);
holder.location.setText(feed.user.location);
holder.topic.setText(Html.fromHtml( "Menyelesaikan Tantangan " + " <font color = '" + String.valueOf(textColor2) + "'>" + feed.topic + "</font>" ) );
Picasso.with(context)
.load(feed.user.avatar)
.into(holder.profile);
PrettyTime prettyTime = new PrettyTime();
String times = prettyTime.format(DateUtil.timeMilisTodate(feed.timestamp * 1000));
holder.times.setText(times);
}
#Override
public int getItemCount() {
return mFeedsList.size();
}
public ArrayList<Feeds> getFeeds() {
return mFeedsList;
}
public void setComplete(int position) {
mFeedsList.get(position).isComplete = 1;
}
public boolean last() {
boolean result = false;
int total = mFeedsList.size();
for (int i = 0; i < mFeedsList.size(); i++) {
if (mFeedsList.get(i).isComplete == 1) {
total--;
}
}
if (total == 1) {
result = true;
}
return result;
}
class ViewHolder extends RecyclerView.ViewHolder {
public TextView fullName;
public TextView location;
public TextView topic;
public ImageView profile;
public TextView times;
public ViewHolder(View itemView) {
super(itemView);
fullName = (TextView) itemView.findViewById(R.id.fullName);
location = (TextView) itemView.findViewById(R.id.location);
topic = (TextView) itemView.findViewById(R.id.topic);
profile = (ImageView) itemView.findViewById(R.id.profil);
times = (TextView) itemView.findViewById(R.id.times);
profile.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(mListener2 != null){
mListener2.onItemClick2(v ,getPosition());
}
}
});
topic.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(mListener != null){
mListener.onItemClick(v ,getPosition());
}
}
});
}
}
public void setClickListener(OnItemClickListener clickListener) {
this.mListener = clickListener;
}
public void setClickListenerProfile(OnItemClickListener clickListener2){
this.mListener2 = clickListener2;
}
public interface OnItemClickListener {
public abstract void onItemClick(View view, int position);
public abstract void onItemClick2(View view, int position);
}
so, in my code i success to display first recylerview with my first xml and i want add new recylerview horizontal with new xml feeds_listviewUser
You can use LinearLayout to wrap both recyclerView.
<android.support.v7.widget.RecyclerView
android:id="#+id/arrayListUser"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:divider="#color/white">
</android.support.v7.widget.RecyclerView>
<android.support.v7.widget.RecyclerView
android:id="#+id/arrayList"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:divider="#color/white">
</android.support.v7.widget.RecyclerView>
And assign horizontal layout manager to one recyclerview and vertical layout manager to other
LinearLayoutManager userManager = new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
arrayListUser.setLayoutManager(userManager);
LinearLayoutManager listManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
arrayList.setLayoutManager(listManager);
Put your recyclerviews in Relative layout.
First add horizontal recyclerView to alignParentTop true and fix height according to visibility of feeds_listviewUser next add vertical recyclerView with layout_below horizontal recyclerview id.

How to create a cardView programatically?

So I have this list of city objects (which contain an image, the name of the city, and a integer value). And for each of these city objects I want to programatically create a new cardView and insert it into a fragment. Currently, nothing shows up...
Here is my fragment xml code.
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.NestedScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingTop="24dp"
android:id="#+id/fragCards_LL">
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
Here is the code for my fragment activity.
public class FragmentCards extends Fragment
{
private ArrayList<CityFolders> cityFolders = new ArrayList<>();
private OnCardsFragmentListener mListener;
private LinearLayout linearLayout;
private View view;
public FragmentCards() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
// Inflate the layout for this fragment
view = inflater.inflate(R.layout.fragment_fragment_cards, container, false);
setUpLinearLayout();
setUpCityFolders();
//TextView myText = (TextView) view.findViewById(R.id.fragCards_numberOfCardsTextContent);
//Toast.makeText(getActivity(), myText.getText(), Toast.LENGTH_SHORT).show();
return inflater.inflate(R.layout.fragment_fragment_cards, container, false);
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnCardsFragmentListener)
{
mListener = (OnCardsFragmentListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnCheeseCategoriesFragmentListener");
}
}
private void setUpLinearLayout()
{
linearLayout = (LinearLayout) view.findViewById(R.id.fragCards_LL);
linearLayout.setOrientation(LinearLayout.VERTICAL);
linearLayout.setLayoutParams(new NestedScrollView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
}
private void setUpCityFolders()
{
if(!Global_Class.getInstance().getValue().cityFoldersArrayList.isEmpty())
{
cityFolders = Global_Class.getInstance().getValue().cityFoldersArrayList;
for(CityFolders cityFolder : cityFolders)
{
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
lp.setMargins(64,64,64,64);
lp.height = 200;//180dp = 720pixels
lp.width = 1408;//330dp = 1320 pixels.
CardView cityCardView = new CardView(getActivity());// ERROR
cityCardView.setBackgroundColor(000000);
cityCardView.setLayoutParams(lp);
linearLayout.addView(cityCardView, 0);
}
}
}
public interface OnCardsFragmentListener
{
void disableCollapse();
}
}
So, don't know what I am doing wrong here... hope someone can help, maybe point out what im doing wrong?
Also, in my cardView, going horizontally, I want to have an imageview, then a textview, followed by another textview. How would I inflate those parts of the cardView and fill them with an image, and 2 texts from my cityFolder object? Hope you guys can help me with an answer!
Cheers
EDIT:
So i implemented a recycler view and..nothing shows up on the screen... This recycler view just holds simple views with each view having an imageview and a textview, and nothing shows up..
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingTop="24dp"
android:id="#+id/fragCards_LL">
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/fragCards_RecyclerView">
</android.support.v7.widget.RecyclerView>
</LinearLayout>
Here is my xml code for the view for each item in the recycler view
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="100dp"
android:layout_height="100dp"
android:src="#drawable/fullstar"
android:id="#+id/fragCardsCity_imageview"
android:layout_gravity="center_vertical"
android:padding="8dp"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Star City"
android:layout_gravity="center_vertical"
android:id="#+id/fragCardsCity_textView"
android:padding="8dp"/>
</LinearLayout>
And finally, here is my java code.
public class FragmentCards extends Fragment
{
private ArrayList<CityFolders> cityFolders = new ArrayList<>();
private LinearLayout linearLayout;
private View rootView;
private RecyclerView recyclerView;
private CityViewAdapter cityAdapter;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
// Inflate the layout for this fragment
rootView = inflater.inflate(R.layout.fragment_cards, container, false);
linearLayout = (LinearLayout) rootView.findViewById(R.id.fragCards_LL);
recyclerView = (RecyclerView) rootView.findViewById(R.id.fragCards_RecyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
cityAdapter = new CityViewAdapter(getActivity(),getData());
recyclerView.setAdapter(cityAdapter);
recyclerView.setItemAnimator(new DefaultItemAnimator());
return rootView;
}
public static ArrayList<myData> getData()
{
ArrayList<myData> data = new ArrayList<>();
int[] icons = {R.drawable.fullstar,R.drawable.fullstar,R.drawable.fullstar,R.drawable.fullstar};
String[] titles = {"San Francisco","Seattle","Tokyo","Osaka"};
for(int i = 0; i < titles.length && i < icons.length; i++)
{
myData current = new myData();
current.iconId = icons[i];
current.cityName = titles[i];
data.add(current);
}
return data;
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
private static class myData
{
private int iconId;
private String cityName;
}
private class CityViewAdapter extends RecyclerView.Adapter<CityViewAdapter.MyViewHolder>
{
private LayoutInflater inflater;
private ArrayList<myData> infoList = new ArrayList<>();
public CityViewAdapter(Context context, ArrayList<myData> data)
{
inflater = LayoutInflater.from(context);
this.infoList = data;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
View view = inflater.inflate(R.layout.fragment_cards_cityview,parent,false);
MyViewHolder holder = new MyViewHolder(view);//special way to avoid "findViewById everytime you make a view
return holder;
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position)
{
myData current = infoList.get(position);
holder.title.setText(current.cityName);
holder.icon.setImageResource(current.iconId);
}
#Override
public int getItemCount() {
return 0;
}
class MyViewHolder extends RecyclerView.ViewHolder
{
TextView title;
ImageView icon;
public MyViewHolder(View itemView)
{
super(itemView);
title = (TextView) itemView.findViewById(R.id.fragCardsCity_textView);
icon = (ImageView) itemView.findViewById(R.id.fragCardsCity_imageview);
}
}
}
}

ReclyclerView and CardView, onclick method perform the action on several CardViews at same time

I've got a RecyclerView which populates from an ArrayList. The output is a CardView layout.
In the Cardview, there are 2 buttons amongst other Views.
They only have to read the current value of a TextView, which by default is 1, and increase or decrease it.
The Arraylist contains 8 items.
When I run the app the UI works fine. Trouble is when I try to modify the value of the TextView.
The value is correctly increased and decreased on the CardView I'm working on, but ALSO the value is modified on another CardView. And in that second CardView, modifying its TextView value, also modifies the first one.
So, what am I doing wrong?
This is my Fragment:
public class Fragment_rosas extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.layout_rosas,container,false);
RecyclerView recyclerview_rosas;
RecyclerView.Adapter adaptador_rv_rosas;
RecyclerView.LayoutManager lm_rosas;
List rosas = new ArrayList();
rosas.add(new Tropa(1,R.drawable.minibarbaro, getResources().getString(R.string.barbaro),7,1));
recyclerview_rosas = (RecyclerView) view.findViewById(R.id.recyclerView_tropasRosas);
recyclerview_rosas.setHasFixedSize(true);
lm_rosas = new LinearLayoutManager(getContext());
recyclerview_rosas.setLayoutManager(lm_rosas);
adaptador_rv_rosas = new AdaptadorTropa(rosas);
recyclerview_rosas.setAdapter(adaptador_rv_rosas);
return view;
}
}
And here the part of code on my Adapter:
#Override
public void onBindViewHolder(final TropaViewHolder viewHolder, int i) {
viewHolder.imagen.setImageResource(items.get(i).getImagen());
viewHolder.nombre.setText(items.get(i).getNombre());
viewHolder.maxnivel.setText(String.valueOf(items.get(i).getNivelMax()));
viewHolder.espacioencamp.setText((String.valueOf(items.get(i).getEspacioEnCamp())));
final String nombre = items.get(i).getNombre();
final int maxnivel = items.get(i).getNivelMax();
viewHolder.nivelmas.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String niveltemp = viewHolder.nivel.getText().toString();
String nivelmaxtemp = viewHolder.maxnivel.getText().toString();
int nivel = Integer.parseInt(niveltemp);
int maxxnivel = Integer.parseInt(nivelmaxtemp);
int nuevonivel = nivel+1 ;
if (nuevonivel<=maxxnivel) {
viewHolder.txtv_nivel.setText(String.valueOf(nuevonivel));
}
}
});
My OnCreateViewHolder (nothing really happens here):
#Override
public TropaViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.cardview, viewGroup, false);
return new TropaViewHolder(v);
}
Here is the solution, as mentioned in the comment above, it addresses two problems:
1. positiontoValueMap - saves current value for each position
2. onclicklistener is passed to the ViewHolder in onCreateViewHolder
Adapter Class
public class MyAdapter extends RecyclerView.Adapter {
private Context context;
private List<String> dataList;
private Map<Integer, Integer> positionToValueMap = new HashMap<>();
public MyAdapter(Context context, List<String> dataList) {
this.context = context;
this.dataList = dataList;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(context).inflate(R.layout.recycler_view_item, null, false);
return new MyViewHolder(view, new OnRecyclerItemClickListener());
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
((MyViewHolder) holder).onRecyclerItemClickListener.updatePosition(position);
((MyViewHolder) holder).position.setText("" + position);
((MyViewHolder) holder).title.setText(dataList.get(position));
int valueToDisplay = 1;
if(positionToValueMap.containsKey(position)) {
valueToDisplay = positionToValueMap.get(position);
} else {
positionToValueMap.put(position, valueToDisplay);
}
((MyViewHolder) holder).valueView.setText("value: " + valueToDisplay);
}
#Override
public int getItemCount() {
return dataList.size();
}
private class MyViewHolder extends RecyclerView.ViewHolder {
private OnRecyclerItemClickListener onRecyclerItemClickListener;
private TextView position;
private TextView title;
private TextView valueView;
public MyViewHolder(View itemView, OnRecyclerItemClickListener onRecyclerItemClickListener) {
super(itemView);
itemView.setOnClickListener(onRecyclerItemClickListener);
this.onRecyclerItemClickListener = onRecyclerItemClickListener;
this.position = (TextView) itemView.findViewById(R.id.position);
this.title = (TextView) itemView.findViewById(R.id.title);
this.valueView = (TextView) itemView.findViewById(R.id.value_view);
}
}
private class OnRecyclerItemClickListener implements View.OnClickListener {
private int position = -1;
public void updatePosition(int position) {
this.position = position;
}
#Override
public void onClick(View v) {
int oldValue = positionToValueMap.get(position); // get current value
oldValue++; // increment
positionToValueMap.put(position, oldValue); // save current value
notifyItemChanged(position); // update clicked view so that it picks up the new saved value from the positionToValueMap in onBindViewHolder
}
}
}
RecyclerView item layout
<TextView
android:id="#+id/position"
android:layout_width="30dp"
android:layout_height="50dp"
android:textColor="#android:color/white"
android:gravity="center"
android:background="#android:color/holo_green_light"
android:layout_alignParentLeft="true"/>
<TextView
android:id="#+id/title"
android:layout_width="50dp"
android:layout_height="50dp"
android:textColor="#android:color/white"
android:gravity="center"
android:background="#android:color/holo_green_dark"
android:layout_toRightOf="#id/position" />
<TextView
android:id="#+id/value_view"
android:layout_width="match_parent"
android:layout_height="50dp"
android:textColor="#android:color/white"
android:gravity="center"
android:background="#android:color/holo_green_light"
android:layout_toRightOf="#id/title"
android:layout_alignParentRight="true"/>
</RelativeLayout>
And Activity to test it out
public class MainActivity extends AppCompatActivity {
private RecyclerView recyclerView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
recyclerView.setAdapter(new MyAdapter(getApplicationContext(), getSampleData()));
}
private static List<String> getSampleData() {
List<String> dataList = new ArrayList<>();
dataList.add("zero");
dataList.add("one");
dataList.add("two");
dataList.add("three");
dataList.add("four");
dataList.add("five");
dataList.add("six");
dataList.add("seven");
dataList.add("eight");
dataList.add("nine");
dataList.add("ten");
dataList.add("eleven");
dataList.add("twelve");
dataList.add("thirteen");
dataList.add("fourteen");
dataList.add("fifteen");
dataList.add("sixteen");
dataList.add("seventeen");
dataList.add("eighteen");
dataList.add("nineteen");
dataList.add("twenty");
return dataList;
}
}
activity layout
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/root_view"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/white"/>
</RelativeLayout>

Categories

Resources