7

Currently a beginner at android development and I've been following some exercises/tutorial here and there and I'm facing a problem where the distance between in items in RecyclerView is too far apart from each other as shown in the picture below. How do I make it closer to each other? I've been searching all over but nothing works.

EDIT : After changing android:layout_height = "match_parent" to android:layout_height = "wrap_content"there is still no changes to the layout.

So I include my java classes along

RecyclerView Screenshot

Here is my .xml

custom_row_news_items.xml

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceSmall"
        android:text="Small Text"
        android:id="@+id/date_text"
        android:layout_alignParentTop="true"
        android:layout_alignParentEnd="true" />

    <ImageView
        android:src="@drawable/img"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/thumb_img"
        android:layout_below="@+id/date_text"
        android:layout_centerHorizontal="true" />

    <TextView
        android:background="#006699"
        android:gravity="center"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:text="Large Text"
        android:id="@+id/title_text"
        android:layout_alignBottom="@+id/thumb_img"
        android:layout_centerHorizontal="true" />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:text="Medium Text"
        android:id="@+id/des_text"
        android:layout_below="@+id/thumb_img"
        android:layout_centerHorizontal="true" />
</RelativeLayout>

content_navigation_drawer.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:showIn="@layout/app_bar_navigation_drawer"
tools:context="com.example.azrie.dummyvoicethenews.NavigationDrawer">

<android.support.v7.widget.RecyclerView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/recyclerView"/>
</RelativeLayout>

Here is my java classes

NavigationDrawer.java

import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.support.design.widget.NavigationView;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;

public class NavigationDrawer extends AppCompatActivity
    implements NavigationView.OnNavigationItemSelectedListener {

   RecyclerView recyclerView;

   @Override
   protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_navigation_drawer);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
    fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                    .setAction("Action", null).show();
        }
    });

    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
        this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
    drawer.setDrawerListener(toggle);
    toggle.syncState();

    NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
    navigationView.setNavigationItemSelectedListener(this);

    recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
    RSSread rssRead;
    rssRead = new RSSread(this,recyclerView);
    rssRead.execute();
}

@Override
public void onBackPressed() {
    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    if (drawer.isDrawerOpen(GravityCompat.START)) {
        drawer.closeDrawer(GravityCompat.START);
    } else {
        super.onBackPressed();
    }
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.navigation_drawer, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    return super.onOptionsItemSelected(item);
}

@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected(MenuItem item) {
    // Handle navigation view item clicks here.
    int id = item.getItemId();

    if (id == R.id.nav_camera) {
        // Handle the camera action
    } else if (id == R.id.nav_gallery) {

    } else if (id == R.id.nav_slideshow) {

    } else if (id == R.id.nav_manage) {

    } else if (id == R.id.nav_share) {

    } else if (id == R.id.nav_send) {

    }

    DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
    drawer.closeDrawer(GravityCompat.START);
    return true;
    }
}

RSSread.java

public class RSSread extends AsyncTask{

Context context;
ProgressDialog progressDialog;
//RSS address
String address = "https://www.sciencemag.org/rss/news_current.xml";
URL url;
//Global initialization for other class to access
ArrayList<FeedItem> feedItems;
RecyclerView recyclerView;

public RSSread(Context context, RecyclerView recyclerView){
    //Initialize recycle view
    this.recyclerView = recyclerView;
    //Initialize progress dialog
    this.context = context;
    progressDialog = new ProgressDialog(context);
    progressDialog.setMessage("Loading....");
}

@Override
protected void onPreExecute() {
    //display progress dialog before fetching data
    progressDialog.show();
    super.onPreExecute();
}

@Override
protected void onPostExecute(Object o) {
    super.onPostExecute(o);
    //dismiss the "Loading..." progress dialog
    progressDialog.dismiss();
    MyAdapter adapter = new MyAdapter(context,feedItems);
    recyclerView.setLayoutManager(new LinearLayoutManager(context));
    recyclerView.setAdapter(adapter);
}

@Override
protected Object doInBackground(Object[] objects) {
    ProcessXml(Getdata()); 
    return null;
}

private void ProcessXml(Document data) {
    //If data is present or not = null
    if(data!=null){
        //ArrayList is created to store every item into a single item
        feedItems = new ArrayList<>();
        //Return document element name that is RSS ( Exercise Part 1 )
        //Log.d("Root", data.getDocumentElement().getNodeName());
        //Element object that store "Root" element
        Element root = data.getDocumentElement();
        //Items are inside channel and channel tag is first child of root tag
        Node channel = root.getChildNodes().item(1);
        //Store all child of channel element
        NodeList items = channel.getChildNodes();

        //Loop through each child of element
        //Output testing
        //Log.d("ItemsLength",Integer.toString(items.getLength()));
        for (int i = 0; i < items.getLength(); i++){
            //Create new node that will store data
            Node currentChild = items.item(i);

            //Check currentChild node is item node
            if (currentChild.getNodeName().equalsIgnoreCase("item")){
                //Create a new feed item for every item
                FeedItem item = new FeedItem(); //Exercise Part 2 : How to process data
                NodeList itemChild = currentChild.getChildNodes();

                //Loop through all childs with item tag
                for(int j = 0; j < itemChild.getLength(); j++){
                    Node current = itemChild.item(j);
                    //Display context of Node Current ( Exercise Part 1 : How to process data )
                    //Log.d("textContent",current.getTextContent());

                    //check for node title node
                    if(current.getNodeName().equalsIgnoreCase("title")){
                        //Set title from FeedItem into current title
                        item.setTitle(current.getTextContent());
                        //Output test
                        Log.d("CurrentItemTitle",current.getTextContent());
                    }

                    else if(current.getNodeName().equalsIgnoreCase("description")){
                        //Set description from FeedItem into current description
                        item.setDescr(current.getTextContent());
                        //Output test
                        Log.d("CurrentItemDesp",current.getTextContent());

                    }

                    else if(current.getNodeName().equalsIgnoreCase("pubDate")){
                        //Set pubDate from FeedItem into current pubDate
                        item.setPubDate(current.getTextContent());
                        //Output test
                        Log.d("CurrentItemPubDate",current.getTextContent());

                    }

                    else if(current.getNodeName().equalsIgnoreCase("link")){
                        //Set link from FeedItem into current link
                        item.setLink(current.getTextContent());
                        //Output test
                        Log.d("CurrentItemLink",current.getTextContent());

                    }

                    else if(current.getNodeName().equalsIgnoreCase("media:thumbnail")){
                        String url = current.getAttributes().item(0).getTextContent();
                        item.setThumbnailUrl(url);
                        //Output test
                        Log.d("CurrentItemThumbnailUrl",current.getTextContent());

                    }
                }

                feedItems.add(item);
                Log.d("ItemTitle",item.getTitle());
                Log.d("ItemDescription",item.getDescr());
                Log.d("ItemLink",item.getLink());
                Log.d("ItemPubDate",item.getPubDate());
                Log.d("ItemThumbnailUrl",item.getThumbnailUrl());

            }
        }
    }
}

//method that return Document type
public Document Getdata(){

    try {
        //Passing the string to URL (From Address)
        url = new URL(address);
        //Open connection
        HttpURLConnection connection;
        connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("GET");
        InputStream inputStream = connection.getInputStream();
        //Create new instance of document build
        DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = builderFactory.newDocumentBuilder();
        //Return XML document
        Document xmlDoc = builder.parse(inputStream);
        //Return xmlDoc
        return xmlDoc;

    } catch (Exception e) {
        e.printStackTrace();
        return null;
    }

}

}

MyAdapter.java

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {
ArrayList<FeedItem> feedItems;
Context context;

public MyAdapter(Context context,ArrayList<FeedItem> feedItems){
    this.feedItems = feedItems;
    this.context = context;
}

@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view = LayoutInflater.from(context).inflate(R.layout.custom_row_news_items,parent,false);
    MyViewHolder holder = new MyViewHolder(view);
    return holder;
}

@Override
public void onBindViewHolder(MyViewHolder holder, int position) {

}

@Override
public int getItemCount() {
    return feedItems.size();
}

public class MyViewHolder extends RecyclerView.ViewHolder {
    public MyViewHolder(View itemView) {
        super(itemView);
    }
}
}

Sorry it is a little bit messy. I'm still not used to the formatting here.

TapanHP
  • 5,969
  • 6
  • 37
  • 66
azriebakri
  • 1,131
  • 2
  • 11
  • 36

5 Answers5

5

In the custom_row_news_items.xml, android:layout_height="match_parent" should be android:layout_height="wrap_content. Because of match_parent, it is taking the space of the entire screen. Always remember that the single row for recyclerview should have height wrap_content if it has vertical layout.

You can also try to change the recyclerview height width parameters to

    android:layout_width="match_parent"
    android:layout_height="match_parent"

I am speculating that because your height is set to wrap content, it is only taking a single row. But with match_parent, it will accomodate as many as it can on the screen.

suku
  • 10,507
  • 16
  • 75
  • 120
  • Hello and thank you for your respond. Thanks to your explanation now I have more understanding how it works. But even after changing `android:layout_height` it still have a big gap in between. Maybe there is something wrong with my Java instead ? – azriebakri Jul 19 '16 at 04:49
  • Also please understand how to use align parameter in relativelayouts. You have said `title_text` alignBottom with `thumb_img` but both have `layout_width="match_parent"`. So it means that the textview and imageview both are in same row and occupy the total screen width. This cannot be possible. But it is not giving any error, still it is wrong to do so – suku Jul 19 '16 at 05:47
  • Thank you, I should learn more about the syntax. It's solved now. Have a nice day :) – azriebakri Jul 19 '16 at 12:43
5

just change your parent layout height from being android:layout_height="match_parent" to android:layout_height="wrap_content and it will solve your problem, as your container of row layout has wrap_content and your row layout tries to match height of parent it will fill a full screen, and your single component has taken a full height of screen.

changes in row layout:

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceSmall"
        android:text="Small Text"
        android:id="@+id/date_text"
        android:layout_alignParentTop="true"
        android:layout_alignParentEnd="true" />

    <ImageView
        android:src="@drawable/img"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/thumb_img"
        android:layout_below="@+id/date_text"
        android:layout_centerHorizontal="true" />

    <TextView
        android:background="#006699"
        android:gravity="center"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:text="Large Text"
        android:id="@+id/title_text"
        android:layout_alignBottom="@+id/thumb_img"
        android:layout_centerHorizontal="true" />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:text="Medium Text"
        android:id="@+id/des_text"
        android:layout_below="@+id/thumb_img"
        android:layout_centerHorizontal="true" />
</RelativeLayout>
TapanHP
  • 5,969
  • 6
  • 37
  • 66
  • Hello and thank you for your help. I have tried that but nothing seems to change. There is still big gap between it. I post my java class thinking the problem might originated from there. – azriebakri Jul 19 '16 at 05:12
1

Modify your custom_row_news_items.xml as follows.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceSmall"
        android:text="Small Text"
        android:id="@+id/date_text"
        android:layout_alignParentTop="true"
        android:layout_alignParentEnd="true" />

    <ImageView
        android:src="@drawable/img"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/thumb_img"
        android:layout_below="@+id/date_text"
        android:layout_centerHorizontal="true" />

    <TextView
        android:background="#006699"
        android:gravity="center"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:text="Large Text"
        android:id="@+id/title_text"
        android:layout_alignBottom="@+id/thumb_img"
        android:layout_centerHorizontal="true" />

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:text="Medium Text"
        android:id="@+id/des_text"
        android:layout_below="@+id/thumb_img"
        android:layout_centerHorizontal="true" />
</RelativeLayout>

Set the parent RelativeLayout height as wrap_content. Currently its set to match_parent which is taking the spaces.

Reaz Murshed
  • 23,691
  • 13
  • 78
  • 98
  • Hello and thanks. I have tried your solution but the problem still remain. I included together my java code thinking the source of the problem might originated from there. – azriebakri Jul 19 '16 at 05:07
1

This is happening even when you change the RelativeLayout's height to wrap_content because RelativeLayout does not know how tall itself should be.

Set the RelativeLayout's height to wrap_content and try adding the following to the last TextView.

android:layout_alignParentBottom="true"

This tells the RelativeLayout's bottom to be aligned with the last TextView, so now the RelativeLayout knows where to end.

skhugh
  • 91
  • 2
  • 6
1
<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

Try this I was having the same problem but when i changed it to wrap content it got fixed! The height has to be wrap_content. And it is better to use LinearLayout