Mat0
Mat0

Reputation: 1195

NestedScrollView start position wrong with large layout

I have two problems:

1.

I'm using the CollapsingToolbarLayout with a NestedScrollView were my layout content is.

When the content inside NestedScrollView becomes large it displaces the start position of the view to the middle of the content inside NestedScrollView.

More specifically the problem started after adding the gridView?

How it looks:

http://files.spicygames.net/200000231-ed6afee6df/device-2015-08-11-164306.png?rnd=5004167712759227

2

In the NestedScrollView I have a gridView. This should contain all images from a json response. The amount of images varies so it should wrap_content. However when I set it to wrap_content, only the first row is display and the rest is cut off.

How do I achieve this?

Image of the problem:

http://files.spicygames.net/200000225-45bee46b8e/device-2015-08-11-164028.png?rnd=09583999146707356

My CollapsingToolbarLayout:

<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:background="#fff3f3f3">

<android.support.design.widget.AppBarLayout
    android:id="@+id/app_bar_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
    android:fitsSystemWindows="true">

    <android.support.design.widget.CollapsingToolbarLayout
        android:id="@+id/collapsing_toolbar"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_scrollFlags="scroll|exitUntilCollapsed"
        app:contentScrim="#80000000"
        app:expandedTitleMarginStart="48dp"
        app:expandedTitleMarginEnd="64dp"
        android:fitsSystemWindows="true">

        <ImageView
            android:id="@+id/image"
            android:layout_width="match_parent"
            android:layout_height="420dp"
            android:scaleType="centerCrop"
            android:fitsSystemWindows="true"
            app:layout_collapseMode="parallax"/>



        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
            app:layout_collapseMode="pin" />

    </android.support.design.widget.CollapsingToolbarLayout>

</android.support.design.widget.AppBarLayout>

<android.support.v4.widget.NestedScrollView
    android:id="@+id/scroll"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:clipToPadding="false"
    android:layout_gravity="fill_vertical"
    android:overScrollMode="never"
    android:layout_marginBottom="?attr/actionBarSize"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">


  <------My NestedScrollView Content is here-----> 

</android.support.v4.widget.NestedScrollView>

<android.support.design.widget.FloatingActionButton
    android:id="@+id/fab"
    android:layout_height="wrap_content"
    android:layout_width="wrap_content"
    android:layout_marginEnd="5dp"
    android:layout_marginRight="5dp"
    android:elevation="2dp"
    app:layout_anchor="@id/app_bar_layout"
    app:layout_anchorGravity="bottom|right|end"
    android:src="@drawable/ic_star_white_24dp"

    />

My NestedScrollView Content:

<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="3dp"
android:orientation="vertical"

>


    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/background_with_shadow"
        android:orientation="vertical"
        android:id="@+id/first"
        style="@style/Shadow"
        android:elevation="1dp"
        >

            <TextView
                android:id="@+id/biography_text"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:paddingLeft="5dp"
                android:text="Biography"
                android:padding="5dp"
                android:textSize="15sp"
                android:textColor="@color/PrimaryText"/>


        <TextView
            android:id="@+id/biography"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="5dp"
            android:textSize="12sp"
            android:lineSpacingMultiplier="1.2"
            android:gravity="start"
            android:textColor="@color/SecondaryText"/>


        </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:id="@+id/second"
        android:background="@drawable/background_with_shadow"
        style="@style/Shadow"
        android:elevation="1dp">


        <TextView
            android:id="@+id/companytext1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Images"
            android:paddingTop="5dp"
            android:paddingLeft="5dp"
            android:textSize="15sp"

            android:textColor="@color/PrimaryText"/>

        <android.support.v4.view.ViewPager
            android:id="@+id/viewpager"
            android:layout_width="fill_parent"
            android:layout_height="200dp"
            android:overScrollMode="never"
            android:padding="5dp"

            />



    </LinearLayout>

<LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="150dp"
    android:background="@drawable/background_with_shadow"
    android:orientation="vertical"
    android:id="@+id/thrid"
    style="@style/Shadow"
    android:elevation="1dp"
    android:layout_marginBottom="5dp"
    >

    <TextView
        android:id="@+id/Details_text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingLeft="5dp"
        android:text="Details"
        android:padding="5dp"
        android:textSize="15sp"
        android:textColor="@color/PrimaryText"/>

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


    <TextView
        android:id="@+id/birth_text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="5dp"
        android:text="Birthday"
        android:layout_gravity="start"
        android:textSize="12sp"
        android:lineSpacingMultiplier="1.2"
        android:gravity="start"
        android:textColor="#000000"/>


         <TextView
             android:id="@+id/birth"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:padding="5dp"
             android:layout_toRightOf="@+id/birth_text"
             android:layout_toEndOf="@+id/birth_text"
             android:layout_gravity="end"
             android:textSize="12sp"
             android:lineSpacingMultiplier="1.2"
             android:gravity="start"
             android:textColor="@color/SecondaryText"/>


         <TextView
             android:id="@+id/Place_text"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_below="@+id/birth_text"
             android:padding="5dp"
             android:text="Place of birth"
             android:layout_gravity="start"
             android:textSize="12sp"
             android:lineSpacingMultiplier="1.2"
             android:gravity="start"
             android:textColor="#000000"/>

         <TextView
             android:id="@+id/Place"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:padding="5dp"
             android:layout_toEndOf="@+id/Place_text"
             android:layout_toRightOf="@+id/Place_text"
             android:layout_below="@+id/birth_text"
             android:layout_gravity="end"
             android:textSize="12sp"
             android:lineSpacingMultiplier="1.2"
             android:gravity="start"
             android:textColor="@color/SecondaryText"/>


         <TextView
             android:id="@+id/death_text"
             android:layout_below="@+id/Place_text"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:padding="5dp"
             android:text="Deathday"
             android:layout_gravity="start"
             android:textSize="12sp"
             android:lineSpacingMultiplier="1.2"
             android:gravity="start"
             android:textColor="#000000"/>

         <TextView
             android:id="@+id/death"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:padding="5dp"
             android:layout_below="@+id/Place_text"
             android:layout_toRightOf="@+id/death_text"
             android:layout_toEndOf="@+id/death_text"
             android:layout_gravity="end"
             android:text="-"
             android:layout_marginEnd="5dp"
             android:layout_marginRight="5dp"
             android:textSize="12sp"
             android:lineSpacingMultiplier="1.2"
             android:gravity="start"
             android:textColor="@color/SecondaryText"/>


     </RelativeLayout>

</LinearLayout>

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:id="@+id/fourth"
    android:background="@drawable/background_with_shadow"
    style="@style/Shadow"
    android:elevation="1dp">


    <TextView
        android:id="@+id/grid_text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Also known for"
        android:paddingTop="5dp"
        android:paddingLeft="5dp"
        android:textSize="15sp"
        android:textColor="@color/PrimaryText"/>


    <GridView

        android:layout_width="match_parent"
        android:layout_height="1000dp"
        android:id="@+id/upcoming_gridlayout"
        style="@style/Shadow"
        android:elevation="1dp"
        android:numColumns="2"
        >

    </GridView>





</LinearLayout>

<View
    android:layout_width="wrap_content"
    android:layout_height="?attr/actionBarSize">

</View>
</LinearLayout>

My Activity CrewCastSingleItem:

public class CrewCastSingleItem extends Activity {

// create var
String ProfileImage;
String Id;
String Name;
String ProfilePathUrl;

String biography;
String name;
String placeOfBirth;
String deathday;
String birthday;




ImageAdapter adapter;

CrewCastGridViewAdapter Gridadapter;
GridView Gridv;


ArrayList<HashMap<String, String>> mylistForPersonImages;

ArrayList<HashMap<String, String>> mylistForPersonFilmImages;


JSONObject json = null;
JSONArray results = null;

private static final String apiKey = "Mykey";
private static final String tmdbURL = "MyURl";


static final String TAG_POSTERPATH = "poster_path";
static final String TAG_TITLE = "original_title";
static final String TAG_ID = "id";


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.cast_single_item);

    // Get specific movie data

    Intent i = getIntent();
    // Get the result of poster

    // Get the result of movie details for textviews
    ProfileImage = i.getStringExtra("profile_path");
    Name = i.getStringExtra("name");
    Id = i.getStringExtra("credit_id");

    ProfilePathUrl = "http://image.tmdb.org/t/p/w500" + ProfileImage;





    // Locate Imageviews
    ImageView ImagePoster = (ImageView) findViewById(R.id.image);

    // load images url into poster

    Picasso.with(getApplicationContext()).load(ProfilePathUrl).into(ImagePoster);


    CollapsingToolbarLayout collapsingToolbarLayout = (CollapsingToolbarLayout) findViewById(R.id.collapsing_toolbar);
    collapsingToolbarLayout.setTitle(Name) ;
    collapsingToolbarLayout.setCollapsedTitleTextColor(Color.parseColor("#ffffff"));
    collapsingToolbarLayout.setExpandedTitleTextAppearance(Color.parseColor("#ffffff"));


    // Items for download data
    //Initialize with empty data
    mylistForPersonImages = new ArrayList<HashMap<String, String>>();

    mylistForPersonFilmImages = new ArrayList<HashMap<String, String>>();

    new DownloadJSON().execute();


}



    @Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_upcoming_singe_item, 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);
}



// Downloading data asynchronously
private class DownloadJSON extends AsyncTask<String, String, String> {


    @Override
    protected String doInBackground(String... url) {
        json = JSONfunctions.getJSONfromURL(tmdbURL + "/3/person/" + Id
                + apiKey +"&append_to_response=images,combined_credits");

        try {

            biography =  json.getString("biography");

            birthday =  json.getString("birthday");

            deathday =  json.getString("deathday");

            name =  json.getString("name");

            placeOfBirth =  json.getString("place_of_birth");





            // Get person images

            JSONObject images = json.getJSONObject("images");

            JSONArray Imagearray = images.getJSONArray("profiles");

            for (int i=0; i<Imagearray.length(); i++) {
                HashMap<String, String> map = new HashMap<String, String>();
                JSONObject actor = Imagearray.getJSONObject(i);


                String filepath = actor.getString("file_path");

                map.put("file_path", filepath);


                mylistForPersonImages.add(map);


            }



            JSONObject othermovies = json.getJSONObject("combined_credits");

            JSONArray otherMoviewarray = othermovies.getJSONArray("cast");

            for (int i=0; i<otherMoviewarray.length(); i++) {
                HashMap<String, String> map = new HashMap<String, String>();
                JSONObject actor = otherMoviewarray.getJSONObject(i);


                String filepath = actor.getString(TAG_POSTERPATH);

                String title = actor.getString(TAG_TITLE);

                String id = actor.getString(TAG_ID);

                map.put(TAG_TITLE, title);
                map.put(TAG_ID, id);
                map.put(TAG_POSTERPATH, filepath);



                mylistForPersonFilmImages.add(map);

           //     Log.v("JSON", "output " + map); // remove before release
            }



        } catch (JSONException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return null;
    }


    @Override
    protected void onPostExecute(String result) {

        super.onPostExecute(result);

   TextView biographyView = (TextView) findViewById(R.id.biography);
   biographyView.setText(biography);

        TextView deathView = (TextView) findViewById(R.id.death);
        deathView.setText(deathday);

        TextView birthView = (TextView) findViewById(R.id.birth);
        birthView.setText(birthday);

        TextView placeView = (TextView) findViewById(R.id.Place);
        placeView.setText(placeOfBirth);

        // Locate viewpager
        ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
        adapter = new ImageAdapter(getApplicationContext(), mylistForPersonImages);
        viewPager.setAdapter(adapter);


        Gridv = (GridView) findViewById(R.id.upcoming_gridlayout);

        Gridadapter = new CrewCastGridViewAdapter(getApplicationContext(), mylistForPersonFilmImages);

        Gridv.setAdapter(Gridadapter);



    }

}

}

The GridviewAdapter and it's layout:

public class UpcomingGridViewAdapter extends BaseAdapter {

public boolean pressedMovieItem;

Context context;
ArrayList<HashMap<String, String>> data;
HashMap<String, String>mylist = new HashMap<>();

public UpcomingGridViewAdapter(Context a, ArrayList<HashMap<String, String>> d) {
    context = a;
    data = d;
}

public int getCount() {
    return data.size();
}

public HashMap<String, String> getItem(int position) {
    return data.get(position);
}

public long getItemId(int position) {
    return position;
}

public View getView(final int position, View convertView, ViewGroup parent) {

    if (convertView == null){
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = inflater.inflate(R.layout.upcoming_grid_item, parent, false);
    }
    final ImageView poster = (ImageView) convertView.findViewById(R.id.upcoming_image);

 //   System.out.println(data.get(position));

   //final HashMap<String, String>mylist = data.get(position);
    mylist = data.get(position);

    //     TextView title = (TextView) vi.findViewById(R.id.textView1);
    //    title.setText((CharSequence) mylist.get("title"));

   final String posterPath = mylist.get("poster_path");


    // set image url correctly
    // sizes for image 45, 92, 154, 185, 300, 500
    final String url = "http://image.tmdb.org/t/p/w185" + posterPath;



    if(mylist.get("poster_path") != "null") {
        // load image url into poster
        Picasso.with(context).load(url).into(poster);
    }
    else{

        // load image url into poster
        Picasso.with(context).load(R.drawable.ic_local_movies_black_24dp).into(poster);
        poster.setBackgroundColor(Color.parseColor("#F5F5F5"));
        poster.setScaleType(ImageView.ScaleType.CENTER_INSIDE);


    }

    // Get onclick of item and pass data to singleitemview for upcoming



    convertView.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View arg0) {

            mylist = data.get(position);

            Intent intent = new Intent(context, UpcomingSingleItem.class);

            intent.putExtra("poster_path", mylist.get(Upcoming.TAG_POSTER));

            intent.putExtra("title", mylist.get(Upcoming.TAG_TITLE));

            intent.putExtra("release_date", mylist.get(Upcoming.TAG_RELEASE));

            intent.putExtra("overview", mylist.get(Upcoming.TAG_OVERVIEW));

            intent.putExtra("id", mylist.get(Upcoming.TAG_ID));

            intent.putExtra("vote_average", mylist.get(Upcoming.TAG_VOTE_AVG));


            context.startActivity(intent);

        }
    });

    return convertView;
}



 }

Layout for Grid Item:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_centerHorizontal="true"
android:gravity="center"
>

<ImageView android:layout_width="123.3dp"
    android:layout_height="185.3dp"
    android:id="@+id/upcoming_image"
    android:scaleType="fitXY"

     />

Upvotes: 0

Views: 601

Answers (1)

So i've bumped into the very same issue. However, i use RecyclerView instead of GridView. I have solved the 'showing only the first row' issue by using a custom LayoutManager which extends GridLayoutManager:

    public class WrappingGridLayoutManager extends GridLayoutManager {

    private int[] mMeasuredDimension = new int[2];
    private int rowCount;

    public WrappingGridLayoutManager(Context context, int spanCount, int itemsNo) {
        super(context, spanCount, GridLayoutManager.VERTICAL, false);

        rowCount = itemsNo / spanCount;
        if (itemsNo % spanCount > 0) {
            rowCount = rowCount + 1;
        }
    }

    public WrappingGridLayoutManager(Context context, int spanCount, int itemsNo, int orientation, boolean reverseLayout) {
        super(context, spanCount, orientation, reverseLayout);

        rowCount = itemsNo / spanCount;
        if (itemsNo % spanCount > 0) {
            rowCount = rowCount + 1;
        }
    }

    @Override
    public void onMeasure(RecyclerView.Recycler recycler, RecyclerView.State state,
                          int widthSpec, int heightSpec) {
        final int widthMode = View.MeasureSpec.getMode(widthSpec);
        final int heightMode = View.MeasureSpec.getMode(heightSpec);
        final int widthSize = View.MeasureSpec.getSize(widthSpec);
        final int heightSize = View.MeasureSpec.getSize(heightSpec);

        measureScrapChild(recycler, 0,
                View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
                View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
                mMeasuredDimension);

        int width = mMeasuredDimension[0];
        int height = mMeasuredDimension[1];

        switch (widthMode) {
            case View.MeasureSpec.EXACTLY:
            case View.MeasureSpec.AT_MOST:
                width = widthSize;
                break;
            case View.MeasureSpec.UNSPECIFIED:
        }

        switch (heightMode) {
            case View.MeasureSpec.EXACTLY:
            case View.MeasureSpec.AT_MOST:
                height = heightSize;
                break;
            case View.MeasureSpec.UNSPECIFIED:
        }

        height = height * rowCount;

        setMeasuredDimension(width, height);
    }

    private void measureScrapChild(RecyclerView.Recycler recycler, int position, int widthSpec,
                                   int heightSpec, int[] measuredDimension) {
        if (getItemCount() > 0) {
            View view = recycler.getViewForPosition(position);
            if (view != null) {
                RecyclerView.LayoutParams p = (RecyclerView.LayoutParams) view.getLayoutParams();
                int childWidthSpec = ViewGroup.getChildMeasureSpec(widthSpec,
                        getPaddingLeft() + getPaddingRight(), p.width);
                int childHeightSpec = ViewGroup.getChildMeasureSpec(heightSpec,
                        getPaddingTop() + getPaddingBottom(), p.height);
                view.measure(childWidthSpec, childHeightSpec);
                measuredDimension[0] = view.getMeasuredWidth();
                measuredDimension[1] = view.getMeasuredHeight();
                recycler.recycleView(view);
            }
        }
    }
}

where you supply the number of items when creating an instance of it so that it calculates the height of the view. and then use it for your recyclerView like this:

recyclerView.setLayoutManager(new WrappingGridLayoutManager(this, 2, items.size()));
recyclerView.setAdapter(new YourAdapter(items));

if you have solved the wrong starting position issue, please let me know. thanks

Upvotes: 2

Related Questions