I am implementing RecycleView that will display list of skills those skills passed form another fragment using Parcelable the issue that when I delete item from the skills that display on RecycleView and back to the previous fragment the item also deleted from the orginal arraylist
Here is the Parcelable object
public class Skills implements Parcelable {
private ArrayList<String> skills;
public ArrayList<String> getVacancySkills() {
return skills;
}
public void setSkills(ArrayList<String> skills) {
this.skills = skills;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeStringList(this.skills);
}
public Skills() {
}
protected Skills(Parcel in) {
this.skills = in.createStringArrayList();
}
public static final Parcelable.Creator<Skills> CREATOR = new Parcelable.Creator<Skills>() {
#Override
public Skills createFromParcel(Parcel source) {
return new Skills(source);
}
#Override
public Skills[] newArray(int size) {
return new Skills[size];
}
};
}
and here is the passing data
#OnClick(R.id.card_add_skill)
public void showAddSkills() {
Bundle data = new Bundle();
Skills skills = new Skills();
skills.setSkills(skillsLit);
data.putParcelable(ExtraKeys.VACANCY_SKILLS, skills);
VacancyEditSkillsFragment vacancyEditSkillsFragment = new VacancyEditSkillsFragment();
FragmentUtils.addFragment(
getActivity().getSupportFragmentManager(),
vacancyEditSkillsFragment
,
true,
App.getContext().getString(R.string.skills), data
);
}
and here is the fragment that recive the Parcable arraylist of strings
public class VacancyEditSkillsFragment extends Fragment {
#BindView(R.id.rc_edit_skill_recycle)
RecyclerView editSkillsRecycle;
private Skills mSkills;
private EditVacancySkillsAdapter mEditVacancySkillsAdapter;
public VacancyEditSkillsFragment() {
// Required empty public constructor
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (getArguments() != null) {
mSkills = getArguments().getParcelable(ExtraKeys.VACANCY_SKILLS);
}
mEditVacancySkillsAdapter = new EditVacancySkillsAdapter(mSkills.getVacancySkills());
editSkillsRecycle.setLayoutManager(new LinearLayoutManager(getActivity()));
editSkillsRecycle.setAdapter(mEditVacancySkillsAdapter);
}
public static VacancyEditSkillsFragment newInstance() {
VacancyEditSkillsFragment fragment = new VacancyEditSkillsFragment();
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_vacancy_edit_skills, container, false);
ButterKnife.bind(this, view);
return view;
}
}
and here is the adapter code
public class EditVacancySkillsAdapter extends RecyclerView.Adapter<EditVacancySkillsAdapter.EditSkillViewHolder> {
private List<String> skills;
public class EditSkillViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
#BindView(R.id.tv_skill_name)
TextView skillTitle;
#BindView(R.id.iv_reomve_skill)
ImageView deleteSkill;
public EditSkillViewHolder(View view) {
super(view);
ButterKnife.bind(this, view);
deleteSkill.setOnClickListener(this);
}
#Override
public void onClick(View view) {
if(view.getId()== R.id.iv_reomve_skill)
{
skills.remove(getAdapterPosition());
notifyDataSetChanged();
}
}
}
public EditVacancySkillsAdapter(ArrayList<String> sections) {
this.skills = sections;
if (skills == null) {
skills = new ArrayList<>();
}
}
#Override
public EditSkillViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_edit_vacancy_skill, parent, false);
return new EditSkillViewHolder(itemView);
}
#Override
public void onBindViewHolder(EditSkillViewHolder holder, int position) {
holder.skillTitle.setText(skills.get(position));
}
#Override
public int getItemCount() {
return skills.size();
}
}
This is as expected.
What is parcellable in simple term is:- It allows you to send a Object across different components. You are referencing the same object in both the components. Parcellable has implemented on top the object. So if any change happens to the object anywhere in the component will reflect back to rest of the component which uses the same object.
I hope you understood.
What you should do is send a copy of the object instead of the original object.
How to clone a parcellable object is by this:-
Foo foo1 = new Foo("a", "b", "c");
Parcel p = Parcel.obtain();
p.writeValue(foo1);
p.setDataPosition(0);
Foo foo2 = (Foo)p.readValue(Foo.class.getClassLoader());
p.recycle();
I hope this will help!
Related
When I click on an item, OnItemListener.onItemClick (see in Adapter code) works, and remove the
respective from LiveData<List> mListLivedata (see in ViewModel).
The problem is that this doesn't update recyclerView, despite the fact that there is an
Observer which subscribes on this LiveData. There is still 4 views in recyclerView, but if
if I click on the last item in view (after having already clicked any item before),
it crashes because there is already less by one object in Livedata<List<>> (cause previous click has
deleted one Object). So, the number of Objects in LiveData is reduced by one after click (which
is what I need), but the number of items in view stays the same (which is bug and I don't understant
where is my mistake).
Where is my mistake and what is the solution?
In ViewModel:
public class PersonViewModel extends AndroidViewModel {
private PersonRepository mRepository;
private CompositeDisposable composite = new CompositeDisposable();
private Single<List<Person>> mThreePersons;
private ArrayList<Person> mList = new ArrayList<>();
private MutableLiveData<List<Person>> mListLivedata = new MutableLiveData<>();
public PersonViewModel(#NonNull Application application) {
super(application);
mRepository = new PersonRepository(application);
mThreePersons = mRepository.getThreePersons();
mThreePersons.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new SingleObserver<List<Person>>() {
#Override
public void onSubscribe(Disposable d) {
Log.d(TAG, "onSubscribe(Disposable d): called");
composite.add(d);
}
#Override
public void onSuccess(List<Person> people) {
Log.d(TAG, "onSuccess: called");
mList.addAll(people);
mListLivedata.setValue(mList);
}
#Override
public void onError(Throwable e) {
Log.d(TAG, "onError: called");
Toast.makeText(application, "NO DATA", Toast.LENGTH_SHORT).show();
}
});
}
LiveData<List<Person>> getListLivedata() {
return mListLivedata;
}
public void removePerson(Person person) {
mList.remove(person);
mListLivedata.setValue(mList);
Log.d(TAG, "removePerson: called");
}
}
In Activity:
public class PersonRecyclerActivity extends AppCompatActivity implements PersonRecyclerAdapter.OnItemListener {
private PersonViewModel personRecyclerViewModel;
private PersonRecyclerAdapter personRecyclerAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.recycler_simple_layout);
RecyclerView personRecyclerView = findViewById(R.id.recycler_view);
personRecyclerAdapter =
new MudakRecyclerAdapter(new PersonRecyclerAdapter.PersonRecyclerDiff(), this);
personRecyclerView.setAdapter(personRecyclerAdapter);
personRecyclerView.setLayoutManager(new LinearLayoutManager(this));
personRecyclerViewModel = new ViewModelProvider(this,
ViewModelProvider.AndroidViewModelFactory.getInstance(this.getApplication()))
.get(PersonViewModel.class);
personRecyclerViewModel.getListLivedata().observe(this, personList -> personRecyclerAdapter.submitList(personList));
}
#Override
public void onItemClick(int position) {
Log.d(TAG, "onItemClick: called for " + personRecyclerAdapter.getPersonAt(position).getName() + ", at the position " + position);
personRecyclerViewModel.removePerson(personRecyclerAdapter.getPersonAt(position));
}
}
In Adapter:
public class PersonRecyclerAdapter extends ListAdapter<Person, PersonRecyclerAdapter.PersonRecyclerViewHolder> {
private OnItemListener mOnItemListener;
public interface OnItemListener {
void onItemClick(int position);
}
protected PersonRecyclerAdapter(#NonNull DiffUtil.ItemCallback<Person> diffCallback, OnItemListener onItemListener) {
super(diffCallback);
mOnItemListener = onItemListener;
}
public class PersonRecyclerViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private final TextView mrName;
private final TextView mrStatus;
OnItemListener onItemListener;
public PersonRecyclerViewHolder(#NonNull View itemView, OnItemListener onItemListener) {
super(itemView);
mrName = itemView.findViewById(R.id.tv_rec_name);
mrStatus = itemView.findViewById(R.id.tv_rec_status);
this.onItemListener = onItemListener;
itemView.setOnClickListener(this);
}
#Override
public void onClick(View v) {
onItemListener.onItemClick(getAdapterPosition());
}
}
public Person getPersonAt(int position) {
return getItem(position);
}
#NonNull
#Override
public MudakRecyclerViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.recycler_simple_item, parent, false);
return new MudakRecyclerAdapter.MudakRecyclerViewHolder(view, mOnItemListener);
}
#Override
public void onBindViewHolder(#NonNull MudakRecyclerViewHolder holder, int position) {
Person currentPerson = getItem(position);
holder.mrName.setText(currentPerson.getName());
holder.mrStatus.setText(currentPerson.getStatus());
}
static class PersonRecyclerDiff extends DiffUtil.ItemCallback<Person> {
#Override
public boolean areItemsTheSame(#NonNull Person oldItem, #NonNull Person newItem) {
return oldItem == newItem;
}
#Override
public boolean areContentsTheSame(#NonNull Person oldItem, #NonNull Person newItem) {
return oldItem.getName().equals(newItem.getName());
}
}
}
ListAdapter won't do anything if you submit the same list instance to it that it was previously using, because it is designed to compare two different lists for differences between them. You should make the removePerson() method create a new List instance with the item removed and pass that to the LiveData.
Example:
public void removePerson(Person person) {
mList = new ArrayList(mList); // create a new list with same contents
mList.remove(person); // remove the item from the new list.
mListLivedata.setValue(mList);
Log.d(TAG, "removePerson: called");
}
I have a RecyclerView in which the user can drag and drop an item to a different position in the RecyclerView.
So far everything works fine.
My problem begins when the RecyclerView has more items than it can display. So when it recycle his content. When the user drag and drop an item to a different position and than scroll away from this part the position changes are not saved. The user just see the old positions for the items.
You can see this issue in the .gif below.
I already tried several things out like:
recyclerViewItem.getRecycledViewPool().setMaxRecycledViews(0,0);
recyclerViewItem.setItemViewCacheSize(30);
and
holder.setIsRecyclable(false);
inside of my onBindViewHolder.
But nothing seems to work for me.
Does anyone know a solution for this problem?
My Fragment class:
public class ShoppinglistFragment extends Fragment {
private ViewModel viewModel;
private ShoppinglistAdapter adapterShoppingItem = new ShoppinglistAdapter();
private RecyclerView recyclerViewItem;
private Boolean fragmentStarted = false;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.shoppinglist_layout, container, false);
recyclerViewItem = view.findViewById(R.id.recyclerViewShoppinglist);
return view;
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
viewModel = ViewModelProviders.of(getActivity()).get(ViewModel.class);
fragmentStarted = true;
recyclerViewItem.setLayoutManager(new LinearLayoutManager(getContext()));
recyclerViewItem.setHasFixedSize(false);
recyclerViewItem.getRecycledViewPool().setMaxRecycledViews(0,0);
recyclerViewItem.setItemViewCacheSize(30);
recyclerViewItem.setAdapter(adapterShoppingItem);
ItemTouchHelper.Callback callback =
new ItemMoveCallback(adapterShoppingItem);
ItemTouchHelper touchHelper = new ItemTouchHelper(callback);
touchHelper.attachToRecyclerView(recyclerViewItem);
//fetch all Shoppinglist Items from local storage
viewModel.getAllShoppinglistItems().observe((LifecycleOwner) this, new Observer <List<Shoppinglist>>() {
#Override
public void onChanged(#Nullable List<Shoppinglist> items) {
if (fragmentStarted){
adapterShoppingItem.submitList(items);
fragmentStarted = false;
}
}
});
adapterShoppingItem.setOnPositionChanged(new ShoppinglistAdapter.onPositionChanged() {
#Override
public void onPositionChanged(Shoppinglist fromItem, Shoppinglist toItem, int fromPosition, int toPosition) {
int fromPositionServer = fromItem.getPosition();
int toPositionServer = toItem.getPosition();
fromItem.setPosition(toPositionServer);
toItem.setPosition(fromPositionServer);
//updating Shoppinglist Item locally
viewModel.updateItem(fromItem);
viewModel.updateItem(toItem);
}
});
}
}}
and my Adapter class:
public class ShoppinglistAdapter extends ListAdapter<Shoppinglist, ShoppinglistAdapter.NoteHolder> implements ItemMoveCallback.ItemTouchHelperContract {
public Integer ressourceType;
private onPositionChanged onPositionChanged;
private ArrayList<Shoppinglist> globalItemList = new ArrayList<Shoppinglist>();
public ShoppinglistAdapter() {
super(DIFF_CALLBACK);
Integer valueOf = Integer.valueOf(0);
this.ressourceType = valueOf;
}
private static final DiffUtil.ItemCallback<Shoppinglist> DIFF_CALLBACK = new DiffUtil.ItemCallback<Shoppinglist>() {
#Override
public boolean areItemsTheSame(Shoppinglist oldItem, Shoppinglist newItem) {
return oldItem.getSqlid() == newItem.getSqlid();
}
#Override
public boolean areContentsTheSame(Shoppinglist oldItem, Shoppinglist newItem) {
return oldItem.getTitle().equals(newItem.getTitle());
}
};
#NonNull
#Override
public NoteHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.shoppinglist_item, parent, false);
return new NoteHolder(itemView);
}
#Override
public void onBindViewHolder(#NonNull NoteHolder holder, int position) {
Shoppinglist currentItem = getItem(position);
holder.setIsRecyclable(false);
holder.tv.setText(currentItem.getTitle());
...
}
public Shoppinglist getNoteAt(int position) {
return getItem(position);
}
public class NoteHolder extends RecyclerView.ViewHolder {
private TextView tv;
public NoteHolder(View itemView) {
super(itemView);
tv= itemView.findViewById(R.id.tv);
globalItemList .add(currentNote);
}
}
public interface onPositionChanged {
void onPositionChanged(Shoppinglist fromItem, Shoppinglist toItem, int fromPosition, int toPosition);
}
public void setOnPositionChanged(ShoppinglistAdapter.onPositionChanged listener) {
this.onPositionChanged = listener;
}
#Override
public void onRowMoved(int fromPosition, int toPosition) {
//send switched Items to Fragment
onPositionChanged.onPositionChanged(globalItemList.get(fromPosition), globalItemList.get(toPosition), fromPosition, toPosition);
//switch Items inside of the global Item List
Collections.swap(globalItemList, fromPosition, toPosition);
notifyItemMoved(fromPosition, toPosition);
}
#Override
public void onRowSelected(NoteHolder myViewHolder) {}
#Override
public void onRowClear(NoteHolder myViewHolder) {}
#Override
public int getItemViewType(int position) {
return super.getItemViewType(position);
}
}
The problem is that you should swap items in ListAdapter.mDiffer which holds the current showing list. So, globalItemList in your code is unused. Replace onRowMoved of your adapter with the following one:
#Override
public void onRowMoved(int fromPosition, int toPosition) {
ArrayList<Shoppinglist> list = new ArrayList(getCurrentList());
Collections.swap(list, fromPosition, toPosition);
submitList(list);
}
sorry for my bad english
My problem: when I rotate my application, all data is lost, I am using a ViewModel, my data loads when I push the button, this is my code for test .
https://github.com/elviss116/androidMvvm-master
This is the Fragment :
public class MovieListFragment extends Fragment {
private MovieListViewModel mViewModel;
private List<MovieModel.DataModel> movieList = new ArrayList<>();
private RecyclerView recyclerView;
private MoviesAdapter mAdapter;
private Button cargar;
public static MovieListFragment newInstance() {
return new MovieListFragment();
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container,
#Nullable Bundle savedInstanceState) {
View view= inflater.inflate(R.layout.movie_list_fragment, container, false);
recyclerView = (RecyclerView)view.findViewById(R.id.recycler_view);
cargar = view.findViewById(R.id.btnCargar);
mAdapter = new MoviesAdapter(movieList);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getContext());
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(mAdapter);
return view;
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
cargar.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mViewModel = ViewModelProviders.of(MovieListFragment.this).get(MovieListViewModel.class);
mViewModel.init();
mViewModel.getMovies().observe(MovieListFragment.this, new Observer<MovieModel>() {
#Override
public void onChanged(#Nullable MovieModel movieModels) {
movieList.addAll(movieModels.getData());
mAdapter.notifyDataSetChanged();
}
});
}
});
}
}
this is the ViewModel :
public class MovieModel {
#SerializedName("data")
List<DataModel> data;
public List<DataModel> getData() {
return data;
}
public void setData(List<DataModel> data) {
this.data = data;
}
public class DataModel {
#SerializedName("name")
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
}
this is the adapter :
public class MoviesAdapter extends RecyclerView.Adapter<MoviesAdapter.MyViewHolder> {
private List<MovieModel.DataModel> moviesList;
public class MyViewHolder extends RecyclerView.ViewHolder {
public TextView name;
public MyViewHolder(View view) {
super(view);
name = (TextView) view.findViewById(R.id.name);
}
}
public MoviesAdapter(List<MovieModel.DataModel> moviesList) {
this.moviesList = moviesList;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.movie_list_row, parent, false);
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
MovieModel.DataModel movie = moviesList.get(position);
holder.name.setText(movie.getName());
}
#Override
public int getItemCount() {
return moviesList.size();
}
}
When you rotate your phone the activity gets destroyed and re-created, so that is why you're seeing your data dissapear.
What I would recommend is grabbing and observing the view model when the activity is created, outside of the click listener. This way the fragment will immediately start observing the data when it is rotated, but will only be initialized when the button is clicked.
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mViewModel = ViewModelProviders.of(MovieListFragment.this).get(MovieListViewModel.class);
mViewModel.getMovies().observe(MovieListFragment.this, new Observer<MovieModel>() {
#Override
public void onChanged(#Nullable MovieModel movieModels) {
movieList.addAll(movieModels.getData());
mAdapter.notifyDataSetChanged();
}
});
cargar.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mViewModel.init();
}
});
}
I'm trying to use recyclerview on fragment with dummy data sample, but does not display any results in fragments that I made, but when I tried it on the activity, the desired results appear in the class activity. Here is a method fragment manager that I made to replace each fragment:
public void changeFragment(Fragment targetFragment) {
getSupportFragmentManager().beginTransaction()
.replace(R.id.main_fragment, targetFragment)
.setTransitionStyle(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
.commit();
}
and this is my current line of code to access the target fragment :
setOnItemClickListener(new DrawerItem.OnItemClickListener() {
#Override
public void onClick(DrawerItem drawerItem, long l, int i) {
changeFragment(new NewsFeedSantri().newInstance());
closeDrawer();
}
})
This is my adapter to generate dummy data :
public class NewsFeedAdapter extends RecyclerView.Adapter<NewsFeedAdapter.NewsFeedHolder> {
private List<NewsFeedItem> newsList;
public NewsFeedAdapter() {
super();
newsList = new ArrayList<NewsFeedItem>();
NewsFeedItem nf = new NewsFeedItem();
for (int i=1; i <= 20; i++) {
nf.setNewsTittle("Judul Berita");
nf.setNewsDate("20/12/2015");
nf.setNewsContent("Ini lorem ipsum dll");
newsList.add(nf);
}
}
#Override
public NewsFeedHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.
from(parent.getContext()).
inflate(R.layout.base_newsfeed_item, parent, false);
NewsFeedHolder viewHolder = new NewsFeedHolder(itemView);
return viewHolder;
}
#Override
public void onBindViewHolder(NewsFeedHolder holder, int position) {
NewsFeedItem newsfeed = newsList.get(position);
holder.viewTittle.setText(newsfeed.getNewsTittle());
holder.viewDate.setText(newsfeed.getNewsDate());
holder.viewContent.setText(newsfeed.getNewsContent());
}
#Override
public int getItemCount() {
return newsList.size();
}
public class NewsFeedHolder extends RecyclerView.ViewHolder {
protected TextView viewTittle;
protected TextView viewUrl;
protected TextView viewContent;
protected TextView viewDate;
public NewsFeedHolder(View itemView) {
super(itemView);
viewTittle = (TextView) itemView.findViewById(R.id.news_tittle);
viewDate = (TextView) itemView.findViewById(R.id.news_date);
viewContent = (TextView) itemView.findViewById(R.id.news_content);
}
}
This is NewsFeedItem class :
public class NewsFeedItem {
protected String idNewsTittle;
protected String newsTittle;
protected String newsUrl;
protected String newsContent;
protected String newsDate;
public String getIdNewsTittle() {
return idNewsTittle;
}
public void setIdNewsTittle(String idNewsTittle) {
this.idNewsTittle = idNewsTittle;
}
public String getNewsTittle() {
return newsTittle;
}
public void setNewsTittle(String newsTittle) {
this.newsTittle = newsTittle;
}
public String getNewsUrl() {
return newsUrl;
}
public void setNewsUrl(String newsUrl) {
this.newsUrl = newsUrl;
}
public String getNewsContent() {
return newsContent;
}
public void setNewsContent(String newsContent) {
this.newsContent = newsContent;
}
public String getNewsDate() {
return newsDate;
}
public void setNewsDate(String newsDate) {
this.newsDate = newsDate;
}
And this is my fragment :
public class NewsFeedSantri extends Fragment {
private RecyclerView recList;
public static NewsFeedSantri newInstance() {
NewsFeedSantri fragment = new NewsFeedSantri();
Bundle args = new Bundle();
fragment.setArguments(args);
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.base_newsfeed_rcview, container, false);
recList = (RecyclerView) rootView.findViewById(R.id.news_rcview);
recList.setHasFixedSize(true);
LinearLayoutManager llm = new LinearLayoutManager(getActivity());
llm.setOrientation(LinearLayoutManager.VERTICAL);
recList.setLayoutManager(llm);
NewsFeedAdapter nfa = new NewsFeedAdapter();
recList.setAdapter(nfa);
return rootView;
} }
No error is generated, this is what makes me confused, did I miss something?
I have an issue. Since the Card class is deprecated and the CardBuilder.EMBED_INSIDE is fairly limited. The only option is to use a custom View. I'd also like to use the CardScrollView and the CardScrollAdapter.
visit Google Glass Immersion Custom Layout without CardBuilder.Layout.EMBED_INSIDE
But my problem is, I can't have multiple views.
Here is MyCustomViewClass:
public class MyCustomView extends FrameLayout{
public MyCustomView (Context context) {
super(context);
initView();
}
private void initView()
{
View view = inflate(getContext(), R.layout.imageview, null);
addView(view);
View view2 = inflate(getContext(), R.layout.secondview, null);
addView(view2);
}
And thats my main activity class:
public class InspectionActivity extends Activity {
private CardScrollView mCardScroller;
private GestureDetector mGestureDetector;
private View mView;
private CardScrollView _cardScroller;
private ArrayList<View> _cardsList;
private MyCustomView _myView;
protected List<CardBuilder> mCards;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
createCards();
_cardsList = new ArrayList<View>();
_myView= new MyCustomView (this);
_cardsList.add(_myView);
_cardScroller = new CardScrollView(this) ;
MainCardsScrollAdapter adapter = new MainCardsScrollAdapter(_cardsList);
_cardScroller.setAdapter(adapter);
_cardScroller.activate();
setContentView(_cardScroller);
}
private void createCards() {
mCards = new ArrayList<CardBuilder>();
}
public class MainCardsScrollAdapter extends CardScrollAdapter
{
ArrayList<View> _cardsList;
public MainCardsScrollAdapter(ArrayList<View> cardsList)
{
_cardsList = cardsList;
}
#Override
public int getCount() {
return _cardsList.size();
}
#Override
public Object getItem(int i) {
return _cardsList.get(i);
}
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
return _cardsList.get(i);
}
#Override
public int getPosition(Object o) {
return _cardsList.indexOf(o);
}
#Override
public int getViewTypeCount() {
return CardBuilder.getViewTypeCount();
}
#Override
public int getItemViewType(int position){
return 2;//should be changed, it's just an example
}
} }
Alright so from your post I'm guessing it's only inflating one of your layouts into the CardScrollView try the following.
Create a adapter class that looks something like this
public class mainAdapter extends CardScrollAdapter {
private List<CustomCard> mCards;
private LayoutInflater inflater;
public mainAdapter(List<CustomCard> cards, LayoutInflater inf)
{
this.mCards = cards;
this.inflater = inf;
}
#Override
public int getCount() {
return mCards.size();
}
#Override
public Object getItem(int i) {
return mCards.get(i);
}
#Override
public View getView(int i, View view, ViewGroup viewGroup) {
int card = mCards.get(i).getLayout();
view = inflater.inflate(card, viewGroup, false);
return view;
}
#Override
public int getPosition(Object o) {
return this.mCards.indexOf(o);
}
}
my CustomCard class looks like this, you could just use a List<Integer> instead tho
public class CustomCard {
public int getLayout() {
return layout;
}
public int layout;
public CustomCard(int layout)
{
this.layout = layout;
}
}
In your activity class create and fill a list with the desired layouts and pass them to your adapter as follows.
in the onCreate()
CreateCards();
mCardScroller = new CardScrollView(this);
mCardScroller.setAdapter(new mainAdapter(mCards, getLayoutInflater()));
and the CreateCards() method would look something like this
public void CreateCards() {
mCards.add(new CustomCard(R.layout.firstview));
mCards.add(new CustomCard(R.layout.secondview));
mCards.add(new CustomCard(R.layout.thirdview));
}
Hope this is of use for you