I am trying to handle item clicks on a listview using either the regular AdapterView.OnItemClickedListener or the ButterKnife #OnItemSelected annotation, but none of them work.
I have tried logging to see if any of the clicks come through by:
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Log.e(Overview.class.getSimpleName(), String.valueOf(position));
}
and
#OnItemClick(R.id.tracks)
void onItemSelected(int position){
Log.e("Tracks", String.valueOf(position));
}
but none of them work. What could be the issue?
The code for my class is:
public class Overview extends Fragment implements AdapterView.OnItemClickListener {
private static final String DATA = "data";
public static final int ARTIST = 1;
public static final int ALBUM = 2;
public static final int PLAYLIST = 3;
int source;
RealmList<Track> trackList;
RealmList<Album> albumList;
#BindView(R.id.tracks)
ExpandableHeightListView tracks;
#BindView(R.id.albums)
RecyclerView albums;
#BindView(R.id.albumsLayout)
LinearLayout albumsLayout;
#OnItemClick(R.id.tracks)
void onItemSelected(int position){
Log.e("Tracks", String.valueOf(position));
}
#OnClick({R.id.all_tracks, R.id.all_albums})
public void showMore(View view) {
switch (view.getId()) {
case R.id.all_tracks:
break;
case R.id.all_albums:
break;
}
}
public Overview newInstance(Wrapper wrapper) {
Bundle bundle = new Bundle();
Overview overview = new Overview();
bundle.putParcelable(DATA, Parcels.wrap(wrapper));
overview.setArguments(bundle);
return overview;
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container,
#Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.overview, container, false);
ButterKnife.bind(this, view);
tracks.setExpanded(true);
tracks.setOnItemClickListener(this);
albums.setLayoutManager(new LinearLayoutManager(getActivity(),
LinearLayoutManager.HORIZONTAL, false));
albums.setNestedScrollingEnabled(false);
Wrapper wrapper = Parcels.unwrap(getArguments().getParcelable(DATA));
trackList = wrapper.getTracks();
albumList = wrapper.getAlbums();
source = wrapper.getSource();
setItems(source);
return view;
}
private void setItems(int source) {
if (!trackList.isEmpty()) {
TrackListAdapter trackListAdapter;
switch (source) {
case ARTIST:
RealmList<Track> realmList = new RealmList<>();
ArrayList<Track> list = new ArrayList<>(trackList.size() > 10 ?
trackList.subList(0, 10) : trackList);
realmList.addAll(list);
trackListAdapter = new TrackListAdapter(getActivity(),
R.layout.track_list_item, realmList);
tracks.setAdapter(trackListAdapter);
break;
case PLAYLIST:
trackListAdapter = new TrackListAdapter(getActivity(),
R.layout.track_list_item, trackList);
tracks.setAdapter(trackListAdapter);
break;
case ALBUM:
trackListAdapter = new TrackListAdapter(getActivity(),
R.layout.album_track_list_item, trackList);
tracks.setAdapter(trackListAdapter);
break;
}
}
if (albumList != null && !albumList.isEmpty()) {
albumsLayout.setVisibility(View.VISIBLE);
AlbumsAdapter albumsAdapter = new AlbumsAdapter(getActivity(), albumList);
albums.setAdapter(albumsAdapter);
}
}
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Log.e(Overview.class.getSimpleName(), String.valueOf(position));
}
}
It's layout file is:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/DarkBodyBackground"
android:orientation="vertical">
<TextView
style="#style/DarkThemeHeaderText"
android:text="Top Tracks" />
<com.radioafrica.music.view.ExpandableHeightListView
android:id="#+id/tracks"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="#color/DarkCardBackgroundColor"
android:dividerHeight="1dip"
android:footerDividersEnabled="true"
android:headerDividersEnabled="true" />
<TextView
android:id="#+id/all_tracks"
style="#style/ShowAllText" />
<LinearLayout
android:id="#+id/albumsLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:orientation="vertical"
android:visibility="gone">
<TextView
style="#style/DarkThemeHeaderText"
android:text="Albums" />
<android.support.v7.widget.RecyclerView
android:id="#+id/albums"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/all_albums"
style="#style/ShowAllText" />
</LinearLayout>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
Related
I have a fragment named "Notification fragment" in which I want to show another fragment named "Watching Fragment" using Tab layout . When I run the app, the tab layout bar is visible but the fragments are not visible.
My Fragment inside which other fragments are to be shown (Notifications Fragment)
public class NotificationsFragment extends Fragment{
GridView listv;
FragmentAdapter fragmentAdapter;
private NotificationsViewModel notificationsViewModel;
private FragmentNotificationsBinding binding;
public View onCreateView(#NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
notificationsViewModel =
new ViewModelProvider(this).get(NotificationsViewModel.class);
binding = FragmentNotificationsBinding.inflate(inflater, container, false);
View root = binding.getRoot();
TabLayout tabLayout = root.findViewById(R.id.tabLayout);
ViewPager vp = root.findViewById(R.id.vp2);
fragmentAdapter = new FragmentAdapter(getChildFragmentManager() , tabLayout.getTabCount());
vp.setAdapter(fragmentAdapter);
tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
vp.setCurrentItem(tab.getPosition());
if(tab.getPosition() == 0 || tab.getPosition() == 1 || tab.getPosition() == 2)
fragmentAdapter.notifyDataSetChanged();
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
vp.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
return root; }
My First Fragment (Watching Fragment)
public class WatchingFragment extends Fragment {
ArrayList<String> list = new ArrayList<String>();
GridView gridv1;
private WatchingViewModel mViewModel;
public static WatchingFragment newInstance() {
return new WatchingFragment();
}
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container,
#Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.watching_fragment, container, false);
gridv1 = view.findViewById(R.id.gridv1);
Intent intent = getActivity().getIntent();
String animename = intent.getStringExtra("nameanime");
list.add(animename);
loadData2();
saveData2();
ListNewAdapter adapter = new ListNewAdapter(getContext(), R.layout.watch_list, list);
gridv1.setAdapter(adapter);
gridv1.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
list.remove(position);
adapter.notifyDataSetChanged();
saveData2();
return true;
}
});
return view;
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mViewModel = new ViewModelProvider(this).get(WatchingViewModel.class);
// TODO: Use the ViewModel
}
private void saveData2() {
SharedPreferences sp = getActivity().getSharedPreferences("shared preferences", MODE_PRIVATE);
SharedPreferences.Editor ed = sp.edit();
Gson gson = new Gson();
String json = gson.toJson(list);
ed.putString("anime list", json);
ed.apply();
}
private void loadData2() {
SharedPreferences sp = getActivity().getSharedPreferences("shared preferences", MODE_PRIVATE);
Gson gson = new Gson();
String json = sp.getString("anime list", "");
Type type = new TypeToken<ArrayList<String>>() {}.getType();
list = gson.fromJson(json , type);
if (list == null) {
list = new ArrayList<String>();
}
}
}
My View pager adapter
public class FragmentAdapter extends FragmentPagerAdapter {
int tabcount;
public FragmentAdapter(#NonNull #NotNull FragmentManager fm, int behavior) {
super(fm, behavior);
tabcount = behavior;
}
#NonNull
#NotNull
#Override
public Fragment getItem(int position) {
switch (position){
case 0: return new WatchingFragment();
case 1: return new CompletedFragment();
case 2: return new WantToWatchFragment();
default: return null;
}
}
#Override
public int getCount() {
return 0;
}
}
Notifications Fragment Layout
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.notifications.NotificationsFragment">
<com.google.android.material.tabs.TabLayout
android:id="#+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Watching" />
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Completed" />
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Want To Watch" />
</com.google.android.material.tabs.TabLayout>
<androidx.viewpager.widget.ViewPager
android:id="#+id/vp2"
android:name="com.example.animeguide.ui.notifications.NotificationsFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/tabLayout" />
</androidx.constraintlayout.widget.ConstraintLayout>
Watching Fragment Layout
<?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_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".ui.notifications.FragmentsInsideList.watching.WatchingFragment">
<TextView
android:id="#+id/textView4"
android:layout_width="184dp"
android:layout_height="58dp"
android:text="hello world"
android:textSize="34sp" />
<GridView
android:id="#+id/gridv1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:numColumns="2" />
</LinearLayout>
In order for the Adapter to know how many pages it has, you need to override getCount method. You did override it, but used 0 as the number of pages, thus having no pages.
In your FragmentAdapter class, try changing this:
#Override
public int getCount() {
return 0;
}
To this:
#Override
public int getCount() {
return tabcount;
}
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.
I have 6 fragments in a Sliding tab layout. All of them have RecyclerView implemented in them. I have populated the RecyclerView. But I one of the fragments does not allow me to scroll, but the rest are working fine.
See the gif below:
This is my problem
Genres.java
public class Genres extends Fragment {
private static final String TAG = "Genres";
RecyclerView recyclerView_genre;
GenresAdapter genresAdapter;
ArrayList<GenresModel> Genrelist = new ArrayList<>();
long genreId;
String genreName;
Cursor genrecursor;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.genres_activity, container, false);
recyclerView_genre = view.findViewById(R.id.recyclerView_genre);
recyclerView_genre.setHasFixedSize(true);
LinearLayoutManager genreLayout = new LinearLayoutManager(getContext());
recyclerView_genre.setLayoutManager(genreLayout);
String[] proj1 = {MediaStore.Audio.Genres.NAME, MediaStore.Audio.Genres._ID};
genrecursor=getActivity().getContentResolver().query(MediaStore.Audio.Genres.EXTERNAL_CONTENT_URI,proj1,null, null, null);
if (genrecursor != null) {
if (genrecursor.moveToFirst()) {
do {
genreId = genrecursor.getLong(genrecursor.getColumnIndexOrThrow(MediaStore.Audio.Genres._ID));
genreName = genrecursor.getString(genrecursor.getColumnIndexOrThrow(MediaStore.Audio.Genres.NAME));
GenresModel genresModel = new GenresModel(genreId,genreName );
Genrelist.add(genresModel);
Collections.sort(Genrelist, new Comparator<GenresModel>() {
#Override
public int compare(GenresModel lhs, GenresModel rhs) {
return lhs.getGenreName().compareTo(rhs.getGenreName());
}
});
} while (genrecursor.moveToNext());
}
}
genrecursor.close();
genresAdapter = new GenresAdapter(getContext(),Genrelist);
recyclerView_genre.setAdapter(genresAdapter);
genresAdapter.notifyDataSetChanged();
return view;
}
GenresAdapter.java
public class GenresAdapter extends RecyclerView.Adapter<GenresAdapter.GenresHolder> {
Context gContext;
ArrayList<GenresModel> GenreList = new ArrayList<>();
public GenresAdapter(Context gContext, ArrayList<GenresModel> genreList) {
this.gContext = gContext;
GenreList = genreList;
}
#Override
public GenresAdapter.GenresHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view3 = LayoutInflater.from(gContext).inflate(R.layout.row_genre, parent, false);
return new GenresHolder(view3);
}
#Override
public void onBindViewHolder(GenresAdapter.GenresHolder holder, int position) {
final GenresModel genresModel1 = GenreList.get(position);
holder.genreText.setText( genresModel1.getGenreName());
}
#Override
public int getItemCount() {
return GenreList.size();
}
public class GenresHolder extends RecyclerView.ViewHolder {
TextView genreText;
public GenresHolder(View itemView) {
super(itemView);
genreText = itemView.findViewById(R.id.genreText);
}
}
}
activity_genre.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.support.v7.widget.RecyclerView
android:id="#+id/recyclerView_genre"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="130dp"
>
</android.support.v7.widget.RecyclerView>
</LinearLayout>
row_genre.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="wrap_content"
android:layout_marginLeft="10dp"
android:layout_marginStart="10dp"
android:paddingTop="35dp"
>
<TextView
android:id="#+id/genreText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#ffffff"
android:textSize="14sp"
/>
</LinearLayout>
I found out the solution myself. Actually the the problem was with the viewpager transformation. I applied https://github.com/geftimov/android-viewpager-transformers/wiki/CubeOutTransformer to my viewpager and for some reason my first 3 fragments were working and rest were not!
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 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.