I am trying to scroll to the selected position after screen rotation but nothing is happening.
I have tried many suggestions, but none is working (setSelection, own smooth scroll...)
public class MovieFragment extends Fragment {
// The customised movie adapter
private MovieAdapter mMovieAdapter;
private GridView mGridView;
private static final String SELECTED_POSTER = "stored_position";
private int mPosition = GridView.INVALID_POSITION;
public interface Callback {
/**
* DetailFragmentCallback for when an item has been selected.
*/
void onItemSelectedNormal (Movie movie);
}
public MovieFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
/**
* Function that makes an Async call for the fetch function while passing the sort criteria from the shared preferences.
*/
public void updateMovies (String sortCriteria) {
FetchMoviesTask fmt = new FetchMoviesTask(getActivity(), mMovieAdapter);
fmt.execute(sortCriteria);
}
#Override
public void onStart() {
super.onStart();
}
public void onSortChange () {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
String sortCriteria = prefs.getString(getString(R.string.pref_criteria_key), getString(R.string.pref_criteria_default));
updateMovies(sortCriteria);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mMovieAdapter = new MovieAdapter(getActivity(), new ArrayList<Movie>());
View rootView = inflater.inflate(R.layout.fragment_movie, container, false);
mGridView = (GridView) rootView.findViewById(R.id.gridview_movie);
mGridView.setAdapter(mMovieAdapter);
// Handle a click on a poster.
mGridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Movie movie = mMovieAdapter.getItem(i); // Get the movie object at the appropriate position.
((Callback) getActivity()).onItemSelectedNormal(movie);
mPosition = i;
}
});
if (savedInstanceState != null && savedInstanceState.containsKey(SELECTED_POSTER)) {
mPosition = savedInstanceState.getInt(SELECTED_POSTER);
}
//onSortChange();
return rootView;
}
#Override
public void onSaveInstanceState(Bundle outState) {
if (mPosition != GridView.INVALID_POSITION){
outState.putInt(SELECTED_POSTER, mPosition);
}
super.onSaveInstanceState(outState);
}
#Override
public void onViewStateRestored(#Nullable Bundle savedInstanceState) {
super.onViewStateRestored(savedInstanceState);
if (mPosition != GridView.INVALID_POSITION) {
mGridView.smoothScrollToPosition(mPosition);
}
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
onSortChange();
}
}
Here is my adapter:
public class MovieAdapter extends ArrayAdapter<Movie> {
private static final String LOG_TAG = MovieAdapter.class.getSimpleName();
public MovieAdapter(Activity context, ArrayList<Movie> movies) {
super(context, 0, movies);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
// Gets the Movie object from the ArrayAdapter at the appropriate position
Movie movie = getItem(position);
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(
R.layout.movie_poster, parent, false);
}
ImageView imageView = (ImageView) convertView.findViewById(R.id.poster_view);
Picasso.with(convertView.getContext()).load(movie.getImageURL()).into(imageView);
return convertView;
}
}
My fragment layout:
<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">
<!-- TODO: Update blank fragment layout -->
<GridView
android:id="#+id/gridview_movie"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:verticalSpacing="0dp"
android:horizontalSpacing="0dp"
android:numColumns="auto_fit"
style="#style/MovieGridStyle"
android:stretchMode="columnWidth" />
<TextView
android:id="#+id/no_data_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="#string/empty_fav_list"
android:visibility="invisible"
android:gravity="center"
android:textColor="#bfafaf"
android:textSize="25sp" />
</RelativeLayout>
My images layout, named movie_poster:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="10sp"
android:background="#drawable/touch_selector">
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="fitXY"
android:id="#+id/poster_view"
android:adjustViewBounds="true"/>
</FrameLayout>
Related
In my Activity I have an EditText, a Button and a GridView. The user selects the image from the GridView and enters the name in the EditText, and then clicks the done button.
activity.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:orientation="vertical"
android:id="#+id/l1"
>
<View
android:layout_width="#dimen/btm_sht_line"
android:layout_height="#dimen/btm_sht_height"
android:layout_marginTop="#dimen/btm_top"
android:layout_gravity="center_horizontal"
android:background="#color/colorPrimaryDark"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/header_create_a_new_list"
android:layout_gravity="center_horizontal"
android:layout_marginTop="20dp"
android:textStyle="bold"
/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:id="#+id/l2"
android:layout_gravity="center_horizontal"
android:layout_marginTop="#dimen/marin_top"
>
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/listname"
android:hint="#string/list_title_name"
android:layout_gravity="center_horizontal"
android:layout_marginLeft="#dimen/marin_top"
android:layout_marginStart="#dimen/marin_top"
android:inputType="text"
android:autofillHints="#string/list_title_name" />
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/done"
android:src="#drawable/ic_check_circle"
android:layout_marginRight="15dp"
android:layout_marginEnd="#dimen/marin_top"
android:layout_marginLeft="#dimen/margin_left"
android:layout_marginStart="#dimen/margin_left"
tools:ignore="ContentDescription"
/> </LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/l3"
android:orientation="vertical"
>
<View style="#style/Divider"
android:layout_marginTop="#dimen/marin_top"
/>
</LinearLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/r1"
>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/scroll"
><GridView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/gridview"
android:columnWidth="90dp"
android:numColumns="auto_fit"
android:verticalSpacing="10dp"
android:horizontalSpacing="10dp"
android:stretchMode="columnWidth"
android:gravity="center"
/>
</ScrollView>
</RelativeLayout>
</LinearLayout>
I want to move the selected image and the entered text to another Activity
<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"
tools:context=".CheckslateHome">
<ImageView
android:layout_width="90dp"
android:layout_height="90dp"
android:id="#+id/ima"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/getlistname"
android:text="hi welcome"
android:layout_below="#+id/ima"
/>
</RelativeLayout>
In my code when the user selects the image, before entering the name, it loads to a new empty window. Also I have 6 images in my drawable Folder and only 3 images are being displayed in the GridView.
Java class
public class NewListCreate extends BottomSheetDialogFragment {
Integer[] images={R.drawable.menu,R.drawable.musicbox,R.drawable.shoppingbag,R.drawable.shoppingcart,R.drawable.wallet,R.drawable.weddingdress};
GridView gridView;
ArrayList<imageModel> arrayList;
public NewListCreate() {}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.new_list_create, container, false);
ImageButton done = view.findViewById(R.id.done);
final EditText listname = (EditText) view.findViewById(R.id.listname);
final GridView gridView = (GridView) view.findViewById(R.id.gridview);
arrayList = new ArrayList<imageModel>();
for (int i = 0; i < images.length; i++) {
imageModel imagemodel = new imageModel();
imagemodel.setmThumbIds(images[i]);
//add in array list
arrayList.add(imagemodel);
}
final ImageAdapterGridView adapterGridView = new ImageAdapterGridView(getContext(), arrayList);
gridView.setAdapter(adapterGridView);
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
adapterGridView.setSelectedPosition(i);
adapterGridView.notifyDataSetChanged();
int imageRes = images[i];
Intent intent = new Intent(getContext(),CheckslateHome.class);
intent.putExtra("IMAGE_RES", imageRes);
startActivity(intent);
}
});
return view;
}
}
AdapterClass
public class ImageAdapterGridView extends BaseAdapter {
private int selectedPosition = -1;
Context context;
ArrayList<imageModel> arrayList;
public ImageAdapterGridView(Context context, ArrayList<imageModel> arrayList) {
this.context = context;
this.arrayList = arrayList;
}
#Override
public int getCount() {
return arrayList.size();
}
#Override
public Object getItem(int i) {
return arrayList.get(i);
}
#Override
public long getItemId(int i) {
return i;
}
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
if (view==null)
{
view = LayoutInflater.from(context).inflate(R.layout.image_list, viewGroup, false);
}
ImageView imageView;
imageView = (ImageView) view.findViewById(R.id.image);
imageView.setImageResource(arrayList.get(i).getmThumbIds());
if (i == selectedPosition) {
view.setBackgroundColor(Color.WHITE);
} else {
view.setBackgroundColor(Color.TRANSPARENT);
}
return view;
}
public void setSelectedPosition(int position) {
selectedPosition = position;
}
}
what i was Looking was Something Like this
[![enter image description here][1]][1]
Copy and paste this hope it solve ur Problem
public class NewListCreate extends BottomSheetDialogFragment {
int[] images={R.drawable.menu,R.drawable.musicbox,R.drawable.shoppingbag,R.drawable.shoppingcart,R.drawable.wallet,R.drawable.weddingdress};
int imageRes = images[0];
public NewListCreate() {
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.new_list_create, container, false);
ImageButton done = view.findViewById(R.id.done);
final EditText listname = (EditText) view.findViewById(R.id.listname);
final GridView gridView = (GridView) view.findViewById(R.id.gridview);
final CustomAdpter customAdpter = new CustomAdpter(images,getContext());
gridView.setAdapter(customAdpter);
gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
customAdpter.selectedImage = i;
customAdpter.notifyDataSetChanged();
imageRes = images[i];
}
});
done.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String itemname = listname.getText().toString();
if (!TextUtils.isEmpty(listname.getText().toString())) {
startActivity(new Intent(getContext(), CheckslateHome.class).putExtra("data", itemname).putExtra("image",imageRes));
dismiss();
} else {
Toast.makeText(getContext(), "List Name not Empty ", Toast.LENGTH_SHORT).show();
}
}
});
return view;
}
public class CustomAdpter extends BaseAdapter{
private int[] icons;
private Context context;
private LayoutInflater layoutInflater;
public int selectedImage = 0;
public CustomAdpter(int[] icons, Context context) {
this.icons = icons;
this.context = context;
this.layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return icons.length;
}
#Override
public Object getItem(int i) {
return null;
}
#Override
public long getItemId(int i) {
return 0;
}
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
if (view == null)
{
view = layoutInflater .inflate(R.layout.image_list,viewGroup,false);
}
ImageView imageicons = view.findViewById(R.id.image);
if (i < icons.length) {
imageicons.setImageResource(icons[i]);
if (i != selectedImage) {
imageicons.setImageAlpha(50);
}
imageicons.setScaleType(ImageView.ScaleType.CENTER_CROP);
// imageicons.setLayoutParams(new GridView.LayoutParams(150, 150));
if (i == selectedImage) {
view.setBackgroundColor(Color.WHITE);
} else {
view.setBackgroundColor(Color.TRANSPARENT);
}
};
return view;
}
}
I think what you're looking for is passing data through navigation.
It will allow you send your image and name data from one activity/fragment to the next one.
Check out data-binding as well, might be useful.
In my app,I get some data from my server. They are displayed fine,but when I pass them in my Detailed Fragment,then all views are null:(.
So here is my code.
public class MainActivityFragment extends Fragment {
public static final String TAG = "AelApp";
public static ArrayList<MyModel> listItemsList;
RecyclerView myList;
public static MatchReportsAdapter adapter;
public MainActivityFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
updateMatchReport();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
getActivity().setTitle("Match Report");
View rootView = inflater.inflate(R.layout.fragment_main_activity, container, false);
listItemsList = new ArrayList<>();
myList = (RecyclerView)rootView.findViewById(R.id.listview_match_reports);
final LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
myList.setHasFixedSize(true);
myList.setLayoutManager(linearLayoutManager);
adapter = new MatchReportsAdapter(getActivity(), listItemsList);
myList.setAdapter(adapter);
return rootView;
}
public void updateMatchReport(){
Intent i = new Intent(getActivity(), MatchReport.class);
getActivity().startService(i);
}
}
Adapter
public class MatchReportsAdapter extends
RecyclerView.Adapter<MatchReportsAdapter.RowHolder>{
private List<MyModel> reportsList;
private Context mContext;
private ImageLoader mImageLoader;
private int focused = 0;
public MatchReportsAdapter(Activity activity, List<MyModel> reportsLists){
this.reportsList = reportsLists;
this.mContext=activity;
}
#Override
public RowHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_items,null);
final RowHolder holder = new RowHolder(v);
return holder;
}
#Override
public void onBindViewHolder(RowHolder holder, int position) {
final MyModel listItems = reportsList.get(position);
holder.itemView.setSelected(focused==position);
holder.getLayoutPosition();
mImageLoader = AppController.getInstance().getImageLoader();
holder.thumbnail.setImageUrl(listItems.getImage(),mImageLoader);
holder.thumbnail.setDefaultImageResId(R.drawable.reddit_placeholder);
holder.name.setText(Html.fromHtml(listItems.getTitle()));
holder.relativeLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String article = listItems.getArticle();
String image = listItems.getImage();
Intent i = new Intent(mContext, DetailedActivity.class);
i.putExtra("articleKey",article);
i.putExtra("imageKey",image);
mContext.startActivity(i);
}
});
}
#Override
public int getItemCount() {
return reportsList.size();
}
public class RowHolder extends RecyclerView.ViewHolder{
protected NetworkImageView thumbnail;
protected TextView name;
protected RelativeLayout relativeLayout;
public RowHolder(View itemView) {
super(itemView);
this.relativeLayout = (RelativeLayout)
itemView.findViewById(R.id.recLayout);
this.thumbnail =
(NetworkImageView)itemView.findViewById(R.id.thumbnail);
this.name = (TextView)itemView.findViewById(R.id.title);
}
}
}
DetailedActivity
public class DetailedActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_detailed);
if(savedInstanceState == null){
getSupportFragmentManager()
.beginTransaction()
.add(R.id.detailed_match_reports,new DetailedActivityFragment())
.commit();
}
}
}
DetailedActivityFragment
public class DetailedActivityFragment extends Fragment {
TextView articleTextView;
String image;
String article;
ImageView imageView;
public DetailedActivityFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_detailed_activity, container, false);
articleTextView = (TextView)getActivity().findViewById(R.id.articleTextView);
imageView = (ImageView)getActivity().findViewById(R.id.imageNews);
Intent i = getActivity().getIntent();
article = i.getStringExtra("articleKey");
image = i.getStringExtra("imageKey");
Picasso.with(getActivity()).load(image).into(imageView);
articleTextView.setText(article);
return v;
}
}
All of my data are passed after clicking a row good. I know this as I debug the following lines.
article = i.getStringExtra("articleKey");
image = i.getStringExtra("imageKey");
and see that both String variables are not null. However,the both views(TextView,ImageView) of my detailed fragment are null.
Maybe I am doing something wrong with my xml file,and I don't see it.
activity_main.xml
<FrameLayout 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:id="#+id/match_reports"
tools:context="theo.testing.androidservices.fragments.MainActivityFragment">
</FrameLayout>
fragment_main_activity
<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:id="#+id/recLayout"
tools:context=".activities.MainActivity"
android:background="#fff">
<android.support.v7.widget.RecyclerView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/listview_match_reports"
android:layout_alignParentStart="true"
android:layout_alignParentLeft="true"
/>
</RelativeLayout>
activity_detailed.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/detailed_match_reports"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="theo.testing.androidservices.activities.DetailedActivity"
tools:ignore="MergeRootFrame">
</FrameLayout>
and finally
fragment_detailed_activity
<?xml version="1.0" encoding="utf-8"?>
<ScrollView android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/imageNews"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
xmlns:android="http://schemas.android.com/apk/res/android">
<TextView
android:layout_gravity="center_horizontal"
android:padding="10dp"
android:text="xcvxcvxcv"
android:textColor="#000"
android:layout_marginTop="5dp"
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/articleTextView"/>
</ScrollView>
What am I missing?
Thanks
Theo.
Change these
articleTextView = (TextView)getActivity().findViewById(R.id.articleTextView);
imageView = (ImageView)getActivity().findViewById(R.id.imageNews);
to
articleTextView = (TextView)v.findViewById(R.id.articleTextView);
imageView = (ImageView)v.findViewById(R.id.imageNews);
You'r passing data to DetailActivity. So first retrieve in DetailActivity and then pass to DetailFragment.
Also you need to pass data to DetailFragment using Bundle with setArguments(bundle)
Your Textview articleTextView is in the fragment but you are finding it in the activitys xml:
articleTextView = (TextView)getActivity().findViewById(R.id.articleTextView);
insetad you should do:
articleTextView = (TextView)(v.findViewById(R.id.articleTextView));
Do the same for Imageviewl.
Am trying to make a ui with flipview as in this tutorial. IThe tutorial deals with activities, but i want it in fragments case. That ie, the flip effect as well as its parent is a fragment. When i use activity it works, but on using fragment,only the empty textview shows up. Can anyone help me with this?
This is some part of the code
page.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ff3333" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="300dp">
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#drawable/banner"
android:id="#+id/head"/>
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="20dp"
android:id="#+id/header"
android:gravity="center"/>
</RelativeLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/des"
android:textSize="30dp"
android:gravity="center"/>
</FrameLayout>
fragment_news_feed :
<merge xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:flipview="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<se.emilsjolander.flipview.FlipView
android:id="#+id/flip_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
flipview:orientation="vertical"
tools:context="com.excel.excelapp.fragment.NewsFeedFragment" >
</se.emilsjolander.flipview.FlipView>
<TextView
android:id="#+id/empty_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Empty!"
android:textSize="32sp"
android:visibility="gone" />
</merge>
NewsFeedFragment.java
public class NewsFeedFragment extends Fragment implements NewsFlipAdapter.Callback, FlipView.OnFlipListener, FlipView.OnOverFlipListener{
private FlipView mFlipView;
private NewsFlipAdapter mAdapter;
int i=0,no_of_items=7;
public NewsFeedFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
LinearLayout wrapper = new LinearLayout(getActivity());
View view = inflater.inflate(R.layout.fragment_news_feed, wrapper, true);
setUpView(view);
return wrapper;
}
private void setUpView(View view) {
mFlipView = (FlipView) view.findViewById(R.id.flip_view);
mAdapter = new NewsFlipAdapter(getActivity());
mAdapter.setCallback(this);
mFlipView.setAdapter(mAdapter);
mFlipView.setOnFlipListener(this);
mFlipView.peakNext(false);
mFlipView.setOverFlipMode(OverFlipMode.RUBBER_BAND);
mFlipView.setEmptyView(view.findViewById(R.id.empty_view));
mFlipView.setOnOverFlipListener(this);
}
#Override
public void onPageRequested(int page) {
mFlipView.smoothFlipTo(page);
}
#Override
public void onFlippedToPage(FlipView v, int position, long id) {
Log.i("pageflip", "Page: " + position);
if(position > mFlipView.getPageCount()-3 && mFlipView.getPageCount()<30){
mAdapter.addItems(5);
}
}
#Override
public void onOverFlip(FlipView v, OverFlipMode mode,
boolean overFlippingPrevious, float overFlipDistance,
float flipDistancePerPage) {
Log.i("overflip", "overFlipDistance = "+overFlipDistance);
}
NewsFlipAdapter.java
public class NewsFlipAdapter extends BaseAdapter {
public interface Callback {
public void onPageRequested(int page);
}
static class Item {
static long id = 0;
long mId;
public Item() {
mId = id++;
}
long getId() {
return mId;
}
}
private LayoutInflater inflater;
private Callback callback;
private List<Item> items = new ArrayList<Item>();
public NewsFlipAdapter(Context context) {
inflater = LayoutInflater.from(context);
}
public void setCallback(Callback callback) {
this.callback = callback;
}
#Override
public int getCount() {
return items.size();
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return items.get(position).getId();
}
#Override
public boolean hasStableIds() {
return true;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
holder = new ViewHolder();
convertView = inflater.inflate(R.layout.page, parent, false);
holder.heading = (TextView) convertView.findViewById(R.id.header);
holder.description = (TextView) convertView.findViewById(R.id.des);
holder.header = (ImageView) convertView.findViewById(R.id.head);
// holder.firstPage = (Button) convertView.findViewById(R.id.first_page);
// holder.lastPage = (Button) convertView.findViewById(R.id.last_page);
// holder.firstPage.setOnClickListener(this);
// holder.lastPage.setOnClickListener(this);
// convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
return convertView;
}
static class ViewHolder {
TextView heading;
ImageView header;
TextView description;
}
/* #Override
public void onClick(View v) {
switch(v.getId()){
case R.id.first_page:
if(callback != null){
callback.onPageRequested(0);
}
break;
case R.id.last_page:
if(callback != null){
callback.onPageRequested(getCount()-1);
}
break;
}
}*/
public void addItems(int amount) {
TextView text;
for (int i = 0; i < amount; i++) {
items.add(new Item());
}
notifyDataSetChanged();
}
public void addItemsBefore(int amount) {
for (int i = 0; i < amount; i++) {
items.add(0, new Item());
}
notifyDataSetChanged();
}
I am not a 100 % sure about the following explanation, so please correct me if I am wrong.
The <merge> tag merges the inflated layout with it's parent view.
It generally doesn't seem to sit well with fragments as explained in more detail here.
So try to replace merge with LinearLayout in your fragment_newsfeed_layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:flipview="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<se.emilsjolander.flipview.FlipView
android:id="#+id/flip_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
flipview:orientation="vertical"
tools:context="com.excel.excelapp.fragment.NewsFeedFragment" >
</se.emilsjolander.flipview.FlipView>
<TextView
android:id="#+id/empty_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Empty!"
android:textSize="32sp"
android:visibility="gone" />
</LinearLayout>
I have a GridView that is implemented within an Activity and a Fragment, and contain its own Adapter. It works great, until scrolling, when I try to scroll it appears to leave a background of the first items loaded.
Here's the code I am implementing:
Activity Class
public class FavoriteActivity extends ActionBarActivity {
private final String LOG_TAG = FavoriteActivity.class.getSimpleName();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_favorite);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new FavoriteListFragment())
.commit();
}
}
#Override
protected void onResume() {
super.onResume();
FavoriteListFragment fragment = (FavoriteListFragment)getSupportFragmentManager().findFragmentById(R.id.container);
if ( null != fragment ) {
fragment.onRestartLoader();
}
}
}
Fragment Class
public class FavoriteListFragment extends Fragment implements LoaderManager.LoaderCallbacks<Cursor> {
public static final String LOG_TAG = FavoriteListFragment.class.getSimpleName();
private static final int LOADER = 0;
private static final String SELECTED_KEY = "selected_position";
private ResultListAdapter mAdapter;
private GridView mGridView;
private int mPosition = ListView.INVALID_POSITION;
public static final String[] SMCONTENT_COLUMNS = {
SMDBContract.SMContentEntry.COLUMN_TITLE,
};
static final int COL_TITLE = 0;
#Override
public void onActivityCreated(Bundle savedInstanceState) {
getLoaderManager().initLoader(LOADER, null, this);
super.onActivityCreated(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
mAdapter = new ResultListAdapter(getActivity(), null, 0);
mAdapter.setIsFavoriteView(true);
View rootView = inflater.inflate(R.layout.fragment_favorite, container, false);
mGridView = (GridView) rootView.findViewById(R.id.listview_sm_content_favorite);
mGridView.setAdapter(mAdapter);
if (savedInstanceState != null && savedInstanceState.containsKey(SELECTED_KEY)) {
mPosition = savedInstanceState.getInt(SELECTED_KEY);
}
return rootView;
}
void onRestartLoader() {
getLoaderManager().restartLoader(LOADER, null, this);
}
#Override
public void onSaveInstanceState(Bundle outState) {
// When tablets rotate, the currently selected list item needs to be saved.
// When no item is selected, mPosition will be set to Listview.INVALID_POSITION,
if (mPosition != ListView.INVALID_POSITION) {
outState.putInt(SELECTED_KEY, mPosition);
}
super.onSaveInstanceState(outState);
}
#Override
public Loader<Cursor> onCreateLoader(int i, Bundle bundle) {
String favs = Utility.getFavoritesIds(getActivity());
Uri resultSearchURI = SMDBContract.SMContentEntry
.buildSMContentMultiple(SMDBContract.CATEGORY_SERIE, favs);
Log.d(LOG_TAG,"PREFS URI: "+resultSearchURI);
return new CursorLoader(getActivity(),
resultSearchURI,
SMCONTENT_COLUMNS,
null,
null,
null);
}
#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
mAdapter.swapCursor(data);
mAdapter.setCursor(data);
if (mPosition != ListView.INVALID_POSITION) {
mGridView.smoothScrollToPosition(mPosition);
}
}
#Override
public void onLoaderReset(Loader<Cursor> loader) {
mAdapter.swapCursor(null);
}
}
Adapter
public class ResultListAdapter extends CursorAdapter {
private Context mContext;
private Cursor mCursor;
public ResultListAdapter(Context context, Cursor c, int flags) {
super(context, c, flags);
mContext = context;
mCursor = c;
}
public Cursor getCursor() {
return mCursor;
}
public void setCursor(Cursor mCursor) {
this.mCursor = mCursor;
}
public static class ViewHolder {
public final ImageView iconView;
public final TextView titleView;
public ViewHolder(View view) {
iconView = (ImageView) view.findViewById(R.id.list_item_icon);
titleView = (TextView) view.findViewById(R.id.list_item_title_textView);
}
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
View view = LayoutInflater.from(context).inflate(R.layout.grid_item, parent, false);
ViewHolder viewHolder = new ViewHolder(view);
view.setTag(viewHolder);
return view;
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
ViewHolder viewHolder = (ViewHolder) view.getTag();
if (viewHolder.iconView != null) {
Picasso.with(context)
.load(cursor.getString(ResultListFragment.COL_POSTER))
.fit()
.centerInside()
.into(viewHolder.iconView);
}
if (viewHolder.titleView != null)
viewHolder.titleView.setText(cursor.getString(ResultListFragment.COL_TITLE));
}
}
Activity Layout
<fragment
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:name=".FavoriteListFragment"
tools:context=".FavoriteListFragment"
tools:layout="#android:layout/list_content" />
Fragment Layout
<FrameLayout
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"
tools:context="![enter image description here][1].FavoriteListFragment">
<GridView
android:id="#+id/listview_sm_content_favorite"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:columnWidth="100dp"
android:numColumns="auto_fit"
android:verticalSpacing="5dp"
android:horizontalSpacing="5dp"
android:stretchMode="columnWidth"
android:gravity="center"
/>
</FrameLayout>
Grid Item Layout
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<FrameLayout
android:layout_width="100dp"
android:layout_height="150dp"
android:layout_gravity="center"
>
<ImageView
android:id="#+id/list_item_icon"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#mipmap/ic_launcher"/>
</FrameLayout>
<TextView
android:id="#+id/list_item_title_textView"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:fontFamily="sans-serif-light"
android:layout_gravity="center"
android:textAppearance="?android:textAppearanceMedium"
android:text="My Item Title"/>
</LinearLayout>
UPDATE:
I just found out that by removing this code from the FavoriteActivity.onCreate the error stops... but why!? can somebody tell me
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new FavoriteListFragment())
.commit();
}
Remove following lines from your Grid Item Layout:
from ImageView remove:
android:src="#mipmap/ic_launcher"
from TextView remove:
android:text="My Item Title"
I am new to Android and am trying a sample application for showing ViewPagers in a Master-Detail Flow using custom PagerAdapters and FragmentStatePagerAdapters. My application has a list of dummy items managed by a SQLiteDatabase which contain a title String, a description String, a Boolean like status, and a list of images (I plan to implement them as downloading from String urls but presently I'm just trying with a single image resource). I am having two problems in the Detail View.
My intention is to use a ViewPager with a FragmentStatePagerAdapter to show the detail view, which consists of a ViewPager with a custom PagerAdapter for showing the list of images, TextView for title and description, a ToggleButton for the like status and a delete button for deleting items from the list.
Issues:
The ViewPager with the custom PagerAdapter does not display the image. It occupies the expected space and swipes performed on it also behave as expected. Only the image is not visible.
[RESOLVED] On using the delete button, I am able to delete the item from the database, and also update the Master View accordingly, but I am not able to update the Detail View, and the app crashes.
Here is my code:
Code that calls ItemDetailActivity.java
#Override
public void onClick(View v) {
Intent detailIntent = new Intent(getContext(), ItemDetailActivity.class);
detailIntent.putExtra(ItemDetailFragment.ARG_LIST_POSITION, holder.position);
getContext().startActivity(detailIntent);
}
ItemDetailActivity.java
public class ItemDetailActivity extends FragmentActivity {
static ItemDetailPagerAdapter idpa;
static ViewPager detailPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_item_detail);
idpa = new ItemDetailPagerAdapter(getSupportFragmentManager());
// Show the Up button in the action bar.
getActionBar().setDisplayHomeAsUpEnabled(true);
detailPager = (ViewPager) findViewById(R.id.item_detail_container);
detailPager.setAdapter(idpa);
detailPager.setCurrentItem(getIntent().getIntExtra(ItemDetailFragment.ARG_LIST_POSITION, 0));
}
}
activity_item_detail.xml
<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/item_detail_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.trial.piclist.ItemDetailActivity"
tools:ignore="MergeRootFrame" />
ItemDetailFragment.java
public class ItemDetailFragment extends Fragment {
public static final String ARG_ITEM_ID = "item_id";
public static final String ARG_LIST_POSITION = "list_index";
public static final String ARG_TWO_PANE = "is_two_pane";
int position = -1;
long id = -1;
boolean twoPane = false;
ViewPager pager;
private PicItem mItem;
public ItemDetailFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
twoPane = getArguments().getBoolean(ARG_TWO_PANE, false);
position = getArguments().getInt(ARG_LIST_POSITION, -1);
id = getArguments().getLong(ARG_ITEM_ID, -1);
if (id == -1)
id = ItemListFragment.getIdByPosition(position);
setmItem(id);
}
public void setmItem(long id) {
if (id >= 0) {
try {
ItemListActivity.lds.open();
mItem = ItemListActivity.lds.getById(id);
ItemListActivity.lds.close();
} catch (Exception e) {
System.out.println(e.getMessage());
}
if (mItem != null) {
List<String> pics = new ArrayList<String>();
pics.add("1");
pics.add("2");
pics.add("3");
pics.add("4");
pics.add("5");
mItem.setPics(pics);
}
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_item_detail,
container, false);
DetailViewHolder holder = new DetailViewHolder();
pager = (ViewPager) rootView.findViewById(R.id.pager);
ImagePagerAdapter adapter = new ImagePagerAdapter(mItem, getActivity(),
inflater, position);
pager.setAdapter(adapter);
holder.position = getArguments().getInt(ARG_LIST_POSITION);
holder.ttv = (TextView) rootView.findViewById(R.id.item_title);
holder.dtv = (TextView) rootView.findViewById(R.id.item_detail);
holder.likeButton = (ToggleButton) rootView
.findViewById(R.id.item_like);
holder.deleteButton = (Button) rootView.findViewById(R.id.item_delete);
rootView.setTag(holder);
if (mItem != null) {
holder.ttv.setText(mItem.getTitle());
holder.dtv.setText(mItem.getDescription());
holder.likeButton.setChecked(mItem.getIsLiked());
holder.likeButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
ItemListActivity.lds.open();
ItemListActivity.lds.toggleLike(mItem.getId());
mItem.toggleIsLiked();
ItemListActivity.lds.close();
ItemListFragment.listDisplayHelper.toggleLiked(position);
}
});
holder.deleteButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
ItemListActivity.lds.open();
ItemListActivity.lds.removeItem(mItem.getId());
ItemListActivity.lds.close();
ItemListFragment.listDisplayHelper.remove(position);
ItemListActivity.idpa.notifyDataSetChanged();
// What do I do so that the FragmentStatePagerAdapter is
// updated and the viewpager shows the next item.
}
});
}
return rootView;
}
static private class DetailViewHolder {
TextView ttv;
TextView dtv;
ToggleButton likeButton;
Button deleteButton;
int position;
}
}
fragment_item_detail.xml
<LinearLayout 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:orientation="vertical"
android:padding="16dp"
tools:context="com.trial.piclist.ItemDetailFragment" >
<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="200dip">
</android.support.v4.view.ViewPager>
<TableRow
android:id="#+id/tableRow1"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:id="#+id/item_title"
style="?android:attr/textAppearanceLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/hello"
android:textIsSelectable="true" />
<Space
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1" />
<include
android:layout_width="wrap_content"
android:layout_height="wrap_content"
layout="#layout/controls_layout" />
</TableRow>
<ScrollView
android:id="#+id/descScrollView"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:id="#+id/item_detail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/hello" />
</LinearLayout>
</ScrollView>
</LinearLayout>
controls_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<ToggleButton
android:id="#+id/item_like"
android:layout_width="30dip"
android:layout_height="30dip"
android:layout_gravity="right"
android:background="#android:drawable/btn_star"
android:gravity="center"
android:text="#string/like_list_item"
android:textOff="#string/empty_text"
android:textOn="#string/empty_text" />
<Button
android:id="#+id/item_delete"
style="?android:attr/buttonStyleSmall"
android:layout_width="30dip"
android:layout_height="30dip"
android:background="#android:drawable/ic_menu_delete"
android:text="#string/empty_text" />
</LinearLayout>
Custom PagerAdapter
ImagePagerAdapter.java
public class ImagePagerAdapter extends PagerAdapter {
LayoutInflater inflater;
List<View> layouts = new ArrayList<>(5);
// Constructors.
#Override
public Object instantiateItem(ViewGroup container, int position) {
if (layouts.get(position) != null) {
return layouts.get(position);
}
View layout = inflater.inflate(R.layout.detail_image,
((ViewPager) container), true);
try {
ImageView loadSpace = (ImageView) layout
.findViewById(R.id.detail_image_view);
loadSpace.setBackgroundColor(0x000000);
loadSpace.setImageResource(R.drawable.light_grey_background);
loadSpace.setAdjustViewBounds(true);
} catch (Exception e) {
System.out.println(e.getMessage());
}
layout.setTag(images.get(position));
layouts.set(position, layout);
return layout;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
}
#Override
public int getCount() {
return 5;
}
#Override
public boolean isViewFromObject(View view, Object object) {
return (((View) object).findViewById((view.getId())) != null);
}
}
FragmentPagerAdapter
ItemDetailPagerAdapter.java
public class ItemDetailPagerAdapter extends FragmentStatePagerAdapter {
public ItemDetailPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
Fragment fragment = new ItemDetailFragment();
Bundle args = new Bundle();
args.putLong(ItemDetailFragment.ARG_ITEM_ID, ItemListFragment.getIdByPosition(position));
args.putInt(ItemDetailFragment.ARG_LIST_POSITION, position);
args.putBoolean(ItemDetailFragment.ARG_TWO_PANE, ItemListActivity.mTwoPane);
fragment.setArguments(args);
return fragment;
}
#Override
public int getCount() {
openDatabase();
int c = database.getCount();
closeDatabase();
return c;
}
#Override
public int getItemPosition(Object object) {
long mId = ((ItemDetailFragment) object).getmId();
int pos = POSITION_NONE;
openDatabase();
if (database.contains(mId)) {
pos = database.getPositionById(mId);
}
closeDatabase();
return pos;
}
}
Any help is much appreciated. Thanks :)
In your ItemDetailFragment, remove the viewpager from the holder, it should be directly into the returned view, something like this:
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_item_detail,
container, false);
pager = (ViewPager) rootView.findViewById(R.id.pager);
ImagePagerAdapter adapter = new ImagePagerAdapter(mItem, getActivity(),inflater, position);
pager.setAdapter(adapter);
return rootView;
}
and the ViewHolder pattern should be applied inside your PagerAdapter.
In ImagePagerAdapter.java, correct the isViewFromObject method -
#Override
public boolean isViewFromObject(View view, Object object) {
return (view == (View) object);
}
This will correct the issue of the ImageView.
In ItemDetailPagerAdapter.java, override the getItemPosition method -
#Override
public int getItemPosition(Object object) {
int ret = POSITION_NONE;
long id = ((ItemDetailFragment) object).getId();
openDatabase();
if (databaseContains(id)) {
ret = positionInDatabase(id);
}
closeDatabase();
return ret;
}
On deleting call the FragmentStatePagerAdapter.NotifyDataSetChanged() method. This will make the Adapter update itself on deleting.
Although, the FragmentStatePagerAdapter uses a list of Fragments and of stored states to implement the adapter. That is also causing trouble. To remove that, implement your own list of Fragments.