Reputation: 1195
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
Reputation: 1395
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