onclick issue on Linear layout in HorizontalScrollView - android

I have a RelativeLayout, inside it i have a HorizontalScrollView, inside it i have 10 images with linear layout. I want to set listener on RelativeLayout not on images how I do it.
below is my code.
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="false"
android:focusable="false"
android:focusableInTouchMode="false"
android:layout_below="#+id/ortext">
<HorizontalScrollView
android:id="#+id/hscroll"
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_marginBottom="5dp"
android:background="#f4ede7"
android:focusable="false"
android:scrollbars="#null"
android:clickable="false"
android:focusableInTouchMode="false" >
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:orientation="horizontal"
android:focusable="false"
android:focusableInTouchMode="false"
android:clickable="false" >
<ImageView
android:id="#+id/img1"
android:layout_width="200dp"
android:layout_height="90dp"
android:layout_gravity="center_horizontal"
android:src="#drawable/ic_launcher" />
<ImageView
android:id="#+id/img2"
android:layout_width="200dp"
android:layout_height="90dp"
android:layout_gravity="center_horizontal"
android:src="#drawable/image1" />
<ImageView
android:id="#+id/img3"
android:layout_width="200dp"
android:layout_height="90dp"
android:layout_gravity="center_horizontal"
android:src="#drawable/image1" />
<ImageView
android:id="#+id/img4"
android:layout_width="200dp"
android:layout_height="90dp"
android:layout_gravity="center_horizontal"
android:src="#drawable/image1" />
<ImageView
android:id="#+id/img5"
android:layout_width="200dp"
android:layout_height="90dp"
android:layout_gravity="center_horizontal"
android:src="#drawable/image1" />
<ImageView
android:id="#+id/img6"
android:layout_width="200dp"
android:layout_height="90dp"
android:layout_gravity="center_horizontal"
android:src="#drawable/image1" />
</LinearLayout>
</HorizontalScrollView>
</RelativeLayout>

Set onClickListener on RelativeLayout
RelativeLayout rlMain=findViewById(R.id.rl_main);
rlMain.setOnClickListner(new View.OnClickListener(){
#Override
public void onClick(View v){
//Your code here
}
});
before that remove from RelativeLayout
android:clickable="false"
android:focusable="false"
android:focusableInTouchMode="false"
to make it look like
<RelativeLayout
android:id="#+id/rl_main"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/ortext">
And Add android:clickable="false" All other child of RelativeLayout

If you want to add listener to your RelativeLayout it's similar to how you set Listners to your view's.
RelativeLayout rl = (RelativeLayout) findViewById(R.id.relativelayout);
rl.setOnClickListner(new View.OnClickListener(){
#Override
public void onClick(View v){
//Your code here
}
});

Use RecyclerView instead of HorizontalScrollView
then you can easily get onClick listner for your imageview by decalaring custom recyclerview adapter.
Make click listener in bindView
add this line in gradle
{
compile 'com.android.support:recyclerview-v7:23.1.1'
}
then add recycler view in your xml file (activity_main.xml)
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
Then In MainActivity.java RecyclerView
public class ListActivity extends AppCompatActivity {
ArrayList<String> imagesUrls = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
// ...
// Lookup the recyclerview in activity layout
RecyclerView rvImages = (RecyclerView) findViewById(R.id.recycler_view);
//get images from your method
imagesUrls = getImageUrls();
// Set layout manager to position the items
rvImages .setLayoutManager(new LinearLayoutManager(this));
// Create adapter passing in the sample user data
ImageViewAdapter adapter = new ImageViewAdapter (MainActivity.this,);
// Attach the adapter to the recyclerview to populate items
rvImages .setAdapter(adapter);
// That's all!
}
}
Adapter class
package yourpackage.name;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.ArrayList;
public class ImageViewAdapter extends RecyclerView.Adapter<ImageViewAdapter .ViewHolder> {
ArrayList<String> productList = new ArrayList<String>();
Context mContext;
#Override
public int getItemCount() {
return productList.size();
}
public ImageViewAdapter (Context context, ArrayList<String> item) {
this.productList = item;
this.mContext = context;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int arg1) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.single_imageview_row, parent, false);
return new ViewHolder(v);
}
public class ViewHolder extends RecyclerView.ViewHolder {
ImageView imgPeoples;
public ViewHolder(View itemView) {
super(itemView);
imgPeoples = (ImageView) itemView.findViewById(R.id.img);
}
}
#Override
public void onBindViewHolder(ViewHolder holder, final int position) {
//Set image to imageview
//#Note: here im using universal image loader to load image from url to imageview.
//Utility.setImageUniversalLoader is my methoad to load image from imageurl
Utility.setImageUniversalLoader(mContext,productList.get(position),holder.imgPeoples);
}
}
Create single_imageview_row.xml with imageview in layout folder

Related

Inflating a TextView and an ImageView within a LinearLayout from a RecyclerView

package com.example.android.popularmovies;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import java.util.ArrayList;
public class MovieAdapter extends RecyclerView.Adapter<MovieAdapter.ViewHolder> {
private ArrayList<String> mTrailers;
private Context mContext;
// Provide a suitable constructor (depends on the kind of dataset)
public MovieAdapter(Context context, ArrayList<String> trailers) {
mTrailers = trailers;
mContext = context;
}
// Create new views (invoked by the layout manager)
#Override
public MovieAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
// create a new view
LinearLayout v = (LinearLayout)LayoutInflater.from(parent.getContext())
.inflate(R.layout.trailer_view, parent, false);
ViewHolder vh = new ViewHolder(v);
return vh;
}
public void watchYoutubeVideo(String id) {
Intent appIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("vnd.youtube:" + id));
Intent webIntent = new Intent(Intent.ACTION_VIEW,
Uri.parse("http://www.youtube.com/watch?v=" + id));
try {
mContext.startActivity(appIntent);
} catch (ActivityNotFoundException ex) {
mContext.startActivity(webIntent);
}
}
// Replace the contents of a view (invoked by the layout manager)
#Override
public void onBindViewHolder(final ViewHolder holder, final int position) {
// - get element from your dataset at this position
// - replace the contents of the view with that element
holder.mImageView.setImageResource(R.drawable.ic_play_arrow_black_24dp);
holder.mTextView.setText("Trailer " + (position + 1));
holder.mTextView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
watchYoutubeVideo(mTrailers.get(holder.getAdapterPosition()));
}
});
}
// Return the size of your dataset (invoked by the layout manager)
#Override
public int getItemCount() {
return mTrailers.size();
}
// 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 TextView mTextView;
public ImageView mImageView;
public ViewHolder(View v) {
super(v);
mImageView = v.findViewById(R.id.play_button_image_view);
mTextView = v.findViewById(R.id.movie_text_view);
}
}
}
I want my UI to be like this
With my code however the app looks like this:
Here is my xml resource:
<?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="horizontal">
<ImageView
android:id="#+id/play_button_image_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:maxHeight="10dp"
android:maxWidth="10dp"
android:scaleType="centerInside"
android:src="#drawable/ic_play_arrow_black_24dp"
/>
<TextView
android:id="#+id/movie_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:gravity="center_horizontal"
android:padding="10dp"
android:textSize="16sp" />
</LinearLayout>
Is there a way to implement this without using different viewholders? Can it be done with a single ViewHolder?
I have seen ways to implement different View types with a RecyclerView, but I would prefer to keep my code as simple as possible.
change the height of LinearLayot to "wrap_content". and add gravity as "center_vertical"
change you item's layout like this
<?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:gravity="center_vertical"
android:orientation="horizontal">
<ImageView
android:id="#+id/play_button_image_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:maxHeight="10dp"
android:maxWidth="10dp"
android:scaleType="centerInside"
android:src="#drawable/ic_play_arrow_black_24dp"
/>
<TextView
android:id="#+id/movie_text_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:gravity="center_horizontal"
android:padding="10dp"
android:textSize="16sp"/>
</LinearLayout>
Try android:layout_height="wrap_content", instead of match_parent in LinearLayout.
1) You need to change the height of the layout: android:layout_height="wrap_content"
2) For the ImageView set:
android:layout_width="10dp"
android:layout_height="10dp"
(very small)
You can also use ConstraintLayout like this
<?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="wrap_content">
<ImageView
android:id="#+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_marginLeft="32dp"
android:layout_marginTop="32dp"
android:layout_marginBottom="32dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:srcCompat="#drawable/ic_play_arrow_black_24dp" />
<TextView
android:id="#+id/textView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:text="Trailer 1"
app:layout_constraintBottom_toBottomOf="#+id/imageView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#+id/imageView"
app:layout_constraintTop_toTopOf="#+id/imageView" />
</androidx.constraintlayout.widget.ConstraintLayout>
That being said the easiest solution would be simply using "wrap_content" on your parent layout.
try this
<?xml version="1.0" encoding="utf-8"?><?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:gravity="center_vertical"
android:orientation="horizontal">
<ImageView
android:id="#+id/play_button_image_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="centerInside"
android:src="#drawable/ic_play_arrow_black_24dp" />
<TextView
android:id="#+id/movie_text_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Trailer 1"
android:layout_margin="5dp"
android:padding="10dp"
android:textSize="16sp" />
</LinearLayout>
Output

Android RecycleView missing two textView out of 8

I'm new to Android, and was following the tutorial on the following site:
http://www.androidauthority.com/how-to-build-an-image-gallery-app-718976/
Pretty much got everything to work, got lazy and used the image he provided, just used two of the images and copy to 8. However, can't figure out why two title of the image (img2 and img3) is missing.... they should be doing the same thing
My activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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="com.example.peter.recycleviewtest.MainActivity">
<android.support.v7.widget.RecyclerView
android:id="#+id/imagegallery"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.constraint.ConstraintLayout>
cell_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:background="#FFFFFF"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:layout_height="match_parent"
android:id="#+id/img"
android:adjustViewBounds="true"
android:layout_width="match_parent" />
<TextView
android:id="#+id/title"
android:layout_gravity="center"
android:textColor="#000"
android:textStyle="bold"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
main_activity
package com.example.peter.recycleviewtest;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
private final String image_titles[] = {
"Img1A",
"Img2B",
"Img3C",
"Img4D",
"Img5E",
"Img6F",
"Img7G",
"Img8H",
};
private final Integer image_ids[] = {
R.drawable.img1,
R.drawable.img2,
R.drawable.img3,
R.drawable.img4,
R.drawable.img5,
R.drawable.img6,
R.drawable.img7,
R.drawable.img8,
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RecyclerView recyclerView = (RecyclerView)findViewById(R.id.imagegallery);
recyclerView.setHasFixedSize(true);
RecyclerView.LayoutManager layoutManager = new GridLayoutManager(getApplicationContext(),2);
recyclerView.setLayoutManager(layoutManager);
ArrayList<CreateList> createLists = prepareData();
MyAdapter adapter = new MyAdapter(getApplicationContext(), createLists);
recyclerView.setAdapter(adapter);
}
private ArrayList<CreateList> prepareData(){
ArrayList<CreateList> theimage = new ArrayList<>();
for(int i = 0; i< image_titles.length; i++){
CreateList createList = new CreateList();
createList.setImage_title(image_titles[i]);
Log.d("DEBUG", "Title added: " + image_titles[i]);
createList.setImage_ID(image_ids[i]);
theimage.add(createList);
}
return theimage;
}
}
adaptor
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
private ArrayList<CreateList> galleryList;
private Context context;
public MyAdapter(Context context, ArrayList<CreateList> galleryList) {
this.galleryList = galleryList;
this.context = context;
}
#Override
public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.cell_layout, viewGroup, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(MyAdapter.ViewHolder viewHolder, int i) {
Log.d("DEBUG", "onBindView added: " + galleryList.get(i).getImage_title());
viewHolder.title.setText(galleryList.get(i).getImage_title());
viewHolder.img.setScaleType(ImageView.ScaleType.CENTER_CROP);
viewHolder.img.setImageResource((galleryList.get(i).getImage_ID()));
}
#Override
public int getItemCount() {
return galleryList.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
private TextView title;
private ImageView img;
public ViewHolder(View view) {
super(view);
title = (TextView)view.findViewById(R.id.title);
img = (ImageView) view.findViewById(R.id.img);
}
}
}
Pretty much identical to the tutorial sample... but don't know why this missing title is happening. Thank you in advance.
I believe this is a combination of two things: the use of adjustViewBounds in your itemView layout and the internal behavior of RecyclerView.
Your itemView layout, stripped down, is:
<LinearLayout orientation=vertical>
<ImageView height=match_parent/>
<TextView>
</LinearLayout>
With this layout, I would expect to never see the image title. This is because you are giving the first child of the LinearLayout all of the available height. That leaves no room for the TextView.
However, since you also specified adjustViewBounds="true", you've given yourself a chance. If the image inside your ImageView isn't as tall as the parent, then it will shrink and now you'll have room for the TextView.
It looks like your two images have different dimensions, so sometimes this will happen. Sometimes it will not.
The best way to handle this is to re-write your itemView's layout. I suggest either using a LinearLayout and the layout_weight attribute, or using FrameLayout and overlaying the image title on top of the image.
LinearLayout solution
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFFFFF"
android:orientation="vertical">
<ImageView
android:id="#+id/img"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
<TextView
android:id="#+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:textColor="#000"
android:textStyle="bold"/>
</LinearLayout>
FrameLayout solution
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFFFFF">
<ImageView
android:id="#+id/img"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<TextView
android:id="#+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|center_horizontal"
android:textColor="#000"
android:textStyle="bold"/>
</FrameLayout>

Recycler view and Card View not working properly

Just check out main activity .xml
what i am doing is displaying recycler view beneath a button and edit text ..
the value from edit text is taken made into a card but the problem is the button is not working i dont know why plz help
I am new to Coordinator views so plz pardon me if i doing some noob mistake
AdapterEx.java
import android.support.design.widget.Snackbar;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.List;
public class AdapterEx extends RecyclerView.Adapter<AdapterEx.ViewHolder>{
private List<String> nos;
public AdapterEx(List<String> nos){
this.nos = nos;
}
class ViewHolder extends RecyclerView.ViewHolder{
public TextView number;
public ViewHolder(View itemView) {
super(itemView);
number =
(TextView)itemView.findViewById(R.id.nos);
itemView.setOnClickListener(new View.OnClickListener() {
#Override public void onClick(View v) {
int position = getAdapterPosition();
Snackbar.make(v, "Click detected on item " + position,
Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
}
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
View v = LayoutInflater.from(viewGroup.getContext())
.inflate(R.layout.card, viewGroup, false);
ViewHolder viewHolder = new ViewHolder(v);
return viewHolder;
}
#Override
public void onBindViewHolder(ViewHolder viewHolder, int i) {
viewHolder.number.setText(nos.get(i));
}
#Override
public int getItemCount() {
return nos.size();
}
}
initializing recycler view
recycler = (RecyclerView) findViewById(R.id.rv);
LayoutManager manager = new LinearLayoutManager(this);
recycler.setLayoutManager(manager);
nos = new ArrayList<>();
nos.add("sadasd");
nos.add("sdada");
adapter = new AdapterEx(nos);
recycler.setAdapter(adapter);
recycler.setHasFixedSize(true);
recycler.setItemAnimator(new DefaultItemAnimator());
main activity . xml
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<RelativeLayout 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:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context="com.dev99.mathbuddy.prime"
android:id="#+id/prime"
android:background="#drawable/prime">
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/editText"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:inputType="number|numberDecimal|numberSigned"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="FACTORISE IT!"
android:id="#+id/button5"
android:onClick="checker"
android:nestedScrollingEnabled="false"
android:layout_below="#+id/editText"
android:layout_centerHorizontal="true" />
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/editText2"
android:layout_below="#+id/button5"
android:textAlignment="center"
android:textSize="30dp"
android:textColor="#000000"
android:layout_alignParentStart="false"
android:layout_alignParentLeft="false" />
</RelativeLayout>
<android.support.v7.widget.RecyclerView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/rv">
</android.support.v7.widget.RecyclerView>
</android.support.design.widget.CoordinatorLayout>
card view.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:card_view="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/card_view"
android:layout_gravity="center_horizontal"
android:layout_width="match_parent"
android:layout_margin="10dp"
android:layout_height="wrap_content"
card_view:cardCornerRadius="4dp"
card_view:cardBackgroundColor="#color/bluemat"
card_view:cardElevation="10dp"
card_view:contentPadding="4dp"
android:clickable="true">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/nos"
android:textSize="40dp"
android:textStyle="bold"
android:textAlignment="center"
android:layout_gravity="center"
android:textColor="#color/red"/>
</android.support.v7.widget.CardView>
The problem is RecyclerView with wrap_content.
For some reason, a RecyclerView does not display the last item or the last few items well. The most common problem I experienced is that the last item got cut off.

how to make an expandable list of cardviews?

I searched a lot to find a direct and clear solution for I think a popular problem but unfortunately I couldn't find it.
We want to have a list of cardviews so each card bind to a specific data and each card has a list inside that shows meta or detail data about its parent.
So we have a nested list inside a cardview.
With a simple search, we know that we should use expanded list view which parents items are cardviews and we must have another layout for its child.
So when you click on cards a list of items appears below of your cards on the root.
But we want to show child list inside of cards?
And there is no access to the something like child list id or any other things to refer to a transition animation and change of layout.
So the clear question is how to add a listview inside a cardview?
i follow my work by using tablelayout and table row. and prefer not to use external libraries for stability and version problems.
this is what i mean.
Image that describe my question
If you don't want to use an external library, you can make your CardView expand like this:
Layout file for an expandable CardView
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:card_view="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/cv"
android:layout_marginTop="5dp"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
card_view:cardCornerRadius="5dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="48dp"
>
<TextView
android:id="#+id/textView_name"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:textSize="18sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textStyle="bold" />
<!--My dropdown Button -->
<RelativeLayout
android:id="#+id/button"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_gravity="end"
android:layout_alignParentRight="true"
android:gravity="center"
>
<View
android:layout_width="12dp"
android:layout_height="12dp"
android:background="#drawable/triangle"
android:layout_alignParentRight="false"
android:layout_alignParentEnd="false" />
</RelativeLayout>
</RelativeLayout>
<!--The layout below is my ExpandableLayout -->
<LinearLayout
android:id="#+id/expandableLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<android.support.v7.widget.AppCompatImageView
android:id="#+id/imageView_Owner"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:orientation="vertical">
<TextView
android:id="#+id/textView_Owner"
android:textSize="16sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/textView_OwnerUrl"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</android.support.v7.widget.CardView>
My ExpandableRecyclerAdapter Class
import android.animation.ObjectAnimator;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.util.SparseBooleanArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.LinearInterpolator;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.squareup.picasso.Picasso;
import java.util.List;
public class ExpandableRecyclerAdapter extends RecyclerView.Adapter<ExpandableRecyclerAdapter.ViewHolder> {
private List<Repo> repos;
private SparseBooleanArray expandState = new SparseBooleanArray();
private Context context;
public ExpandableRecyclerAdapter(List<Repo> repos) {
this.repos = repos;
//set initial expanded state to false
for (int i = 0; i < repos.size(); i++) {
expandState.append(i, false);
}
}
#Override
public ExpandableRecyclerAdapter.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
this.context = viewGroup.getContext();
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.expandable_card_row, viewGroup, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(final ExpandableRecyclerAdapter.ViewHolder viewHolder, final int i) {
viewHolder.setIsRecyclable(false);
viewHolder.tvName.setText(repos.get(i).getName());
viewHolder.tvOwnerLogin.setText("Owner: " +repos.get(i).getOwner().getLogin());
viewHolder.tvOwnerUrl.setText(repos.get(i).getOwner().getUrl());
Picasso.with(context)
.load(repos.get(i).getOwner().getImageUrl())
.resize(500, 500)
.centerCrop()
.into(viewHolder.ivOwner);
//check if view is expanded
final boolean isExpanded = expandState.get(i);
viewHolder.expandableLayout.setVisibility(isExpanded?View.VISIBLE:View.GONE);
viewHolder.buttonLayout.setRotation(expandState.get(i) ? 180f : 0f);
viewHolder.buttonLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(final View v) {
onClickButton(viewHolder.expandableLayout, viewHolder.buttonLayout, i);
}
});
}
#Override
public int getItemCount() {
return repos.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
private TextView tvName,tvOwnerLogin, tvOwnerUrl;
private ImageView ivOwner;
public RelativeLayout buttonLayout;
public LinearLayout expandableLayout;
public ViewHolder(View view) {
super(view);
tvName = (TextView)view.findViewById(R.id.textView_name);
tvId = (TextView)view.findViewById(R.id.textView_id);
tvUrl = (TextView)view.findViewById(R.id.textView_url);
tvOwnerLogin = (TextView)view.findViewById(R.id.textView_Owner);
tvOwnerUrl = (TextView)view.findViewById(R.id.textView_OwnerUrl);
ivOwner = (ImageView) view.findViewById(R.id.imageView_Owner);
buttonLayout = (RelativeLayout) view.findViewById(R.id.button);
expandableLayout = (LinearLayout) view.findViewById(R.id.expandableLayout);
}
}
private void onClickButton(final LinearLayout expandableLayout, final RelativeLayout buttonLayout, final int i) {
//Simply set View to Gone if not expanded
//Not necessary but I put simple rotation on button layout
if (expandableLayout.getVisibility() == View.VISIBLE){
createRotateAnimator(buttonLayout, 180f, 0f).start();
expandableLayout.setVisibility(View.GONE);
expandState.put(i, false);
}else{
createRotateAnimator(buttonLayout, 0f, 180f).start();
expandableLayout.setVisibility(View.VISIBLE);
expandState.put(i, true);
}
}
//Code to rotate button
private ObjectAnimator createRotateAnimator(final View target, final float from, final float to) {
ObjectAnimator animator = ObjectAnimator.ofFloat(target, "rotation", from, to);
animator.setDuration(300);
animator.setInterpolator(new LinearInterpolator());
return animator;
}
}
In your Activity/Fragment, set up RecyclerView like this
private RecyclerView recyclerView;
private List<Repo> data;
recyclerView = (RecyclerView)findViewById(R.id.card_recycler_view);
recyclerView.setHasFixedSize(true);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(layoutManager);
//fetch data and on ExpandableRecyclerAdapter
recyclerView.setAdapter(new ExpandableRecyclerAdapter(data));
So, its quite simple to create an expandable CardView without external Library. The code is almost exactly the same as using a normal CardView with RecyclerView, the main change is setting the View.GONE/View.VISIBLE on button click.
You can use ExpandLayout,and then add it in cardview.
<com.kyo.expandablelayout.ExpandableLayout
android:id="#+id/expandlayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="12dp" >
<ImageView
android:id="#+id/imageview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:contentDescription="#null"
android:scaleType="centerCrop"
android:src="#drawable/parent" />
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:contentDescription="#null"
android:scaleType="centerCrop"
android:src="#drawable/child"
app:canExpand="true" />
</com.kyo.expandable.ExpandableLayout>

how to remove empty list item in recycler views?

I'm using recycler view to show items with multiple views. whenever I launch the app some white space is being showed. which is exactly equal to my list items.
I provided the screenshot please go through it.
I think there is no problem with my code.
following is my code
recyclerview
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".activities.GroupView">
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_view_group_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="vertical" >
</android.support.v7.widget.RecyclerView>
</RelativeLayout>
adapter code
import android.content.Context;
import android.support.v7.widget.CardView;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import java.util.List;
import java.util.Objects;
import pdfshare.hemanthreddy.com.pdfshare.R;
import pdfshare.hemanthreddy.com.pdfshare.pojo.PdfItemHolder;
import pdfshare.hemanthreddy.com.pdfshare.pojo.RequestPojo;
public class GroupContentAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
final int PDF = 0,REQUEST = 1;
List<Object> list;
OnClickListener onClickListener;
Context context;
public GroupContentAdapter(List<Object> list, OnClickListener onClickListener, Context context) {
this.list = list;
this.onClickListener = onClickListener;
this.context = context;
}
public class PdfHolder extends RecyclerView.ViewHolder {
TextView pdfName,pdfDescription,Helped,uploadedBy;
Button downloadPdf,viewPdf;
View container;
CardView cardView;
public PdfHolder(View itemView) {
super(itemView);
container = itemView;
uploadedBy = (TextView) itemView.findViewById(R.id.pdf_info_uplodedby);
pdfName = (TextView) itemView.findViewById(R.id.pdf_name);
pdfDescription = (TextView) itemView.findViewById(R.id.pdf_description);
Helped = (TextView) itemView.findViewById(R.id.helped);
downloadPdf = (Button) itemView.findViewById(R.id.download_pdf);
viewPdf = (Button) itemView.findViewById(R.id.view_pdf);
cardView = (CardView) itemView.findViewById(R.id.card_view_pdf_row);
}
}
public class RequestHolder extends RecyclerView.ViewHolder {
View container;
TextView name,request;
public RequestHolder(View itemView) {
super(itemView);
container = itemView;
name = (TextView) itemView.findViewById(R.id.requested_name);
request = (TextView) itemView.findViewById(R.id.request);
}
}
public interface OnClickListener{
public void OnItemClick(View view,int position);
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
RecyclerView.ViewHolder viewHolder;
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
switch (viewType) {
case PDF:
View v1 = inflater.inflate(R.layout.pdf_row_view,parent,false);
viewHolder = new PdfHolder(v1);
break;
case REQUEST:
View v2 = inflater.inflate(R.layout.group_request_row_view,parent,false);
viewHolder = new RequestHolder(v2);
break;
default:
View v3 = inflater.inflate(R.layout.pdf_row_view,parent,false);
viewHolder = new PdfHolder(v3);
}
return viewHolder;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
if(holder.getItemViewType() == PDF)
{
PdfItemHolder pdfItemHolder = (PdfItemHolder) list.get(position);
PdfHolder pdfHolder = (PdfHolder) holder;
if(!TextUtils.isEmpty(pdfItemHolder.getPdfName())) {
pdfHolder.pdfName.setText(pdfItemHolder.getPdfName());
pdfHolder.pdfDescription.setText(pdfItemHolder.getPdfDescription());
pdfHolder.Helped.setText(pdfItemHolder.getHelped());
pdfHolder.uploadedBy.setText(pdfItemHolder.getUplodedBy());
pdfHolder.downloadPdf.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(context, "downloading pdf bitch", Toast.LENGTH_LONG).show();
}
});
pdfHolder.container.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onClickListener.OnItemClick(v, position);
}
});
}
else
{
Toast.makeText(context,"empty",Toast.LENGTH_LONG).show();
Log.e("empty","empty");
pdfHolder.container.setVisibility(View.GONE);
pdfHolder.pdfName.setVisibility(View.GONE);
pdfHolder.pdfDescription.setVisibility(View.GONE);
pdfHolder.Helped.setVisibility(View.GONE);
pdfHolder.downloadPdf.setVisibility(View.GONE);
pdfHolder.uploadedBy.setVisibility(View.GONE);
pdfHolder.viewPdf.setVisibility(View.GONE);
}
}
else
{
RequestHolder requestHolder = (RequestHolder) holder;
RequestPojo requestPojo = (RequestPojo) list.get(position);
requestHolder.name.setText(requestPojo.getName());
requestHolder.request.setText(requestPojo.getRequest());
}
}
#Override
public int getItemCount() {
return list.size();
}
#Override
public int getItemViewType(int position)
{
if(list.get(position) instanceof PdfItemHolder)
return PDF;
else if(list.get(position) instanceof RequestPojo)
return REQUEST
;
return -1;
}
}
also I checked stack overflow to remove spaces and I added some code to adapter to check wheather the data is empty or not, it didn't worked well.
following Is code of row views`group_row_view code
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Requested By : "
android:id="#+id/textView7" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Name"
android:id="#+id/requested_name"
android:layout_alignParentTop="true"
android:layout_toRightOf="#+id/textView7"
android:layout_toEndOf="#+id/textView7" />
<View
android:layout_width="fill_parent"
android:layout_height="2dp"
android:background="#c0c0c0"
android:id="#+id/view1"
android:layout_below="#+id/textView7"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Medium Text"
android:id="#+id/request"
android:lines="2"
android:layout_below="#+id/view1"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"/>
</RelativeLayout>
</android.support.v7.widget.CardView>
code of Pdf_row_view
</LinearLayout>`
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:card_view="http://schemas.android.com/apk/res-auto">
<android.support.v7.widget.CardView
android:id="#+id/card_view_pdf_row"
android:layout_gravity="center"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
card_view:cardCornerRadius="3dp"
card_view:contentPadding="2dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="250dp"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="pdfName"
android:id="#+id/pdf_name"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:textSize="25dp"
android:lines="1" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="pdf descriptionl"
android:id="#+id/pdf_description"
android:layout_below="#+id/pdf_name"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:lines="2" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="View Pdf"
android:id="#+id/view_pdf"
android:layout_alignTop="#+id/download_pdf"
android:layout_toRightOf="#+id/pdf_info_uplodedby"
android:layout_toEndOf="#+id/pdf_info_uplodedby" />
<Button
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Download Pdf"
android:id="#+id/download_pdf"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_below="#+id/pdf_description" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="helped"
android:id="#+id/helped"
android:textSize="15dp"
android:layout_alignBottom="#+id/view_pdf"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<View
android:layout_width="fill_parent"
android:layout_height="2dp"
android:background="#c0c0c0"
android:layout_alignTop="#+id/view_pdf"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:id="#+id/view" />
<View
android:layout_width="fill_parent"
android:layout_height="2dp"
android:background="#c0c0c0"
android:id="#+id/view1"
android:layout_below="#+id/view_pdf"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Upladed by : "
android:id="#+id/pdf_info_uplodedby"
android:layout_below="#+id/view_pdf"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
</RelativeLayout>
</android.support.v7.widget.CardView>
</RelativeLayout>
please help me.. thank you
In all of your list item layout files:
pdf_row_view.xml, group_request_row_view.xml, pdf_row_view.xml
set layout_height="wrap_content" of their root layout
Remove the match_parent and set wrap_content as the layout_height instead in the root of your layout of your list items.
For example your pdf_row_view.xml should look like this
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:card_view="http://schemas.android.com/apk/res-auto">
<android.support.v7.widget.CardView
android:id="#+id/card_view_pdf_row"
android:layout_gravity="center"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
card_view:cardCornerRadius="3dp"
card_view:contentPadding="2dp">
<!-- Other elements in your layout -->
</android.support.v7.widget.CardView>
</RelativeLayout>
See, I've set the android:layout_height="wrap_content" in the root RelativeLayout of your pdf_row_view list item.
Do the same for the other list item layouts.
Just set the height of the rootView of specific viewHolder to 0 like this -
RecyclerView.LayoutParams layoutParams = new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
layoutParams.height = 0;
rootView.setLayoutParams(layoutParams);
where rootView is same as this -
ViewHolder(View view) {
super(view);
rootView = view;
}
Let me know if you want more clarity on this.

Categories

Resources