I have view pager in my app. inside a viewpager there are two fragments [1] and [2] both with list view inside [A] and [B]. when I scroll listview [A] and switch fragment [2] I want listview [B] to be scrolled with the same amount automatically. please help
here is my snippet
public class CurrencyViewPager extends BaseFragment {
private ListView mcurrencyListview;
private GeoCurrencyService mCurrency = GeoCurrencyService.getInstance();
ButtonPressListener buttonListener;
private CurrencyAdapter mCurrencyAdapter;
private String bankName;
private boolean checkFlag;
private ProgressBar mCurrencyProgress;
private TextView mCurrencyLoading;
private List<Currency> mList;
private String recCode;
private static int Firstposition;
private final CurrencyScrollListener listener;
private final int mListViewIndex;
// constructor
public CurrencyViewPager(List<Currency> myList, String name, boolean flag,String code, CurrencyScrollListener listener, int listViewIndex) {
super();
this.mList = myList;
this.bankName = name;
this.checkFlag = flag;
this.recCode = code;
this.listener = listener;
this.mListViewIndex = listViewIndex;
}
// interface
public interface ButtonPressListener {
public void onListItemPressed(Currency object, String name,String code);
}
// attach on listener
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
buttonListener = (ButtonPressListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement onButtonPressed");
}
}
// creating the main View.
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
Log.i("TAG","onCreateView");
View view = inflater.inflate(R.layout.listbuy, container, false);
mcurrencyListview = (ListView) view.findViewById(R.id.BuyList);
mCurrencyAdapter = new CurrencyAdapter(getActivity(),
R.layout.currency_row, mList, checkFlag, getLanguage());
mcurrencyListview.setAdapter(mCurrencyAdapter);
mcurrencyListview.setSelection(Firstposition);
// calling method getCurrency which take bank code as a parameter
/*getCurrency(code,null);*/
// reference to the list view of the corresponding layout
mcurrencyListview.setOnItemClickListener(new OnItemClickListener() {
// onClick on the List item
#Override
public void onItemClick(AdapterView<?> arg0, View arg1,
int position, long arg3) {
// getting Currency object according to the position
Currency currencyObject = mCurrencyAdapter.getItem(position);
// sending the object to the mainActivity
buttonListener.onListItemPressed(currencyObject, bankName,recCode);
}
});
return view;
}
// method getCurrency which takes bank code as a parameter and
// sets the adapter to the list on onPostExecute.
}
and fragment adapter for viewpager
public class ViewPagerAdapter extends FragmentStatePagerAdapter implements
CurrencyScrollListener {
private String nBankName;
private List<Currency> list;
private String mycode;
private CurrencyViewPager[] mFragments = new CurrencyViewPager[2];
private int mCurrentScrollPosition;
#Override
public int getItemPosition(Object object) {
// TODO Auto-generated method stub
return super.getItemPosition(object);
}
public CurrencyViewPager getFCurrencyFragment(int index) {
CurrencyViewPager pager = mFragments[index];
if (pager == null) {
if (index == 0) {
pager = new CurrencyViewPager(list, nBankName, true, mycode,
this, 0);
} else {
pager = new CurrencyViewPager(list, nBankName, false, mycode,
this, 1);
}
mFragments[index] = pager;
}
return pager;
}
public ViewPagerAdapter(FragmentManager fm, List<Currency> currencyList,
String name, String code) {
super(fm);
this.list = currencyList;
this.nBankName = name;
this.mycode = code;
}
#Override
public Fragment getItem(int item) {
Log.i("TAG","getItem");
return getFCurrencyFragment(item);
}
#Override
public int getCount() {
return 2;
}
}
Related
I have this ListView adapter:
public class UpicksAdapter extends BaseAdapter
{
Context context;
List<Upick> upick_list;
public UpicksAdapter(List<Upick> listValue, Context context)
{
this.context = context;
this.upick_list = listValue;
}
#Override
public int getCount()
{
return this.upick_list.size();
}
#Override
public Object getItem(int position)
{
return this.upick_list.get(position);
}
#Override
public long getItemId(int position)
{
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
ViewItem viewItem = null;
if(convertView == null)
{
viewItem = new ViewItem();
LayoutInflater layoutInfiater = (LayoutInflater)this.context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
convertView = layoutInfiater.inflate(R.layout.listview_items, null);
viewItem.SubNameTextView = (TextView)convertView.findViewById(R.id.SubjectNameTextView);
viewItem.SubFullFormTextView = (TextView)convertView.findViewById(R.id.SubjectFullFormTextView);
convertView.setTag(viewItem);
}
else
{
viewItem = (ViewItem) convertView.getTag();
}
viewItem.SubNameTextView.setText(upick_list.get(position).Subject_Name);
viewItem.SubFullFormTextView.setText(upick_list.get(position).Subject_Full_Form);
return convertView;
}
}
class ViewItem
{
TextView SubNameTextView;
TextView SubFullFormTextView;
}
The ListView is in a fragment.
I need to get data from the listview selected item. I have this listener:
UpicksListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
String item = UpicksListView.getItemAtPosition(position).toString();
Log.d("VALOR","VALOR "+item);
}
});
How can I get the values of the selected item?
EDIT:
Complete Fragment code:
public class MisUpicksFragment extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
private SessionManager session;
private ProgressDialog loading;
private EditText txtbusqueda;
private Button botonbuscar,botonrefrescar;
//movies
private static final String TAG = MainActivity.class.getSimpleName();
public List<Upick> upicks;
private RecyclerView recyclerView;
private GridLayoutManager gridLayout;
private UpicksAdapter adapter;
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
private String user_id;
private Button btnNew;
ListView UpicksListView;
ProgressBar progressBar;
String HttpURL = "http://***/upicks_todos.php";
private OnFragmentInteractionListener mListener;
public MisUpicksFragment() {
// Required empty public constructor
}
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* #param param1 Parameter 1.
* #param param2 Parameter 2.
* #return A new instance of fragment MensajesFragment.
*/
// TODO: Rename and change types and number of parameters
public static MisUpicksFragment newInstance(String param1, String param2) {
MisUpicksFragment fragment = new MisUpicksFragment();
Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_misupicks, container, false);
UpicksListView = (ListView) view.findViewById(R.id.UpicksListView);
progressBar = (ProgressBar) view.findViewById(R.id.ProgressBar1);
new ParseJSonDataClass(getActivity()).execute();
UpicksListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
String item = UpicksListView.getItemAtPosition(position).toString();
Log.d("VALOR","VALOR "+item);
}
});
return view;
}
private class ParseJSonDataClass extends AsyncTask<Void, Void, Void> {
public Context context;
String FinalJSonResult;
List<Upick> upickFullFormList;
public ParseJSonDataClass(Context context) {
this.context = context;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... arg0) {
HttpServiceClass httpServiceClass = new HttpServiceClass(HttpURL);
try {
httpServiceClass.ExecutePostRequest();
if (httpServiceClass.getResponseCode() == 200) {
FinalJSonResult = httpServiceClass.getResponse();
if (FinalJSonResult != null) {
JSONArray jsonArray = null;
try {
jsonArray = new JSONArray(FinalJSonResult);
JSONObject jsonObject;
Upick upick;
upickFullFormList = new ArrayList<Upick>();
for (int i = 0; i < jsonArray.length(); i++) {
upick = new Upick();
jsonObject = jsonArray.getJSONObject(i);
upick.Subject_Name = jsonObject.getString("id_servicio");
upick.Subject_Full_Form = jsonObject.getString("cliente_servicio");
upickFullFormList.add(upick);
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} else {
Toast.makeText(context, httpServiceClass.getErrorMessage(), Toast.LENGTH_SHORT).show();
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result)
{
progressBar.setVisibility(View.GONE);
UpicksListView.setVisibility(View.VISIBLE);
if (upickFullFormList != null) {
UpicksAdapter adapter = new UpicksAdapter(upickFullFormList, context);
UpicksListView.setAdapter(adapter);
}
}
}
private void logoutUser() {
session.setLogin(false);
// Launching the login activity
Intent intent = new Intent(getActivity(), LoginActivity.class);
startActivity(intent);
//finish();
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
}
Change this code to setters.
upick.Subject_Name = jsonObject.getString("id_servicio");
upick.Subject_Full_Form = jsonObject.getString("cliente_servicio");
eg:
upick.setSubjectname(jsonObject.getString("id_servicio"));
Then inside onclick you can take values using getters
String item = upicks.get(position).getSubjectname();
parent.getItemAtPosition(position) will return an Object (the model used in your adapter).To get some field from your Object don't call Object.toString(); it will return the object reference not the value that you're looking for. Use Object.yourField; instead.
The ArrayList.get() method is used to get the element of a specified
position within the list.
String str_ITEM= upicks.get(position).yourGETMETHOD();
in your callback listener you have adapter object just use that like below.
UpicksListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
String item = parent.getSelectedItem().toString();
Log.d("VALOR","VALOR "+item);
}
});
I've been working on adapter and tried to update it with notifydatasetchanged. But the problem I face is that after i successfully update the adapter where I can see the changes have been made in the listview, it will then change back to previous data after I return from other fragment. I've heard that adapter will reuse the convert view with same data which cause the problem, but I don't know how to fix this. I've searched for the answer but couldn't find anything similar as most of the answers were all about declaring a new adapter.
Below is part of my code:
1.refresh method in fragment
public void toggleRefreshInBackground(ArrayList<HashMap<String, Object>> list) {
dialog_list.clear();
dialog_list.addAll(list);
adapter.update(list);
}
2.getView() of my adapter
public class DialogListAdapter extends BaseAdapter {
Context context;
private ImageLoader imageLoader;
private static LayoutInflater inflater;
private ArrayList<HashMap<String, Object>> member_list;
private ArrayList<HashMap<String, Object>> member_list2;
private SparseBooleanArray mSelectedItemsIds;
private ArrayList<Integer> selectedItemPosition;
//private static final int droidGreen = Color.parseColor("#A4C639");
//private BadgeView badge;
Resources res;
String sorting;
public DialogListAdapter(Context c,
ArrayList<HashMap<String, Object>>content, String temp_sorting) {
inflater=(LayoutInflater)c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
this.context=c;
this.member_list = content;
this.member_list2 = new ArrayList<>();
this.member_list2.addAll(this.member_list);
res=c.getResources();
this.sorting = temp_sorting;
mSelectedItemsIds = new SparseBooleanArray();
selectedItemPosition = new ArrayList<>();
}
#Override
public int getCount() {
// TODO Auto-generated method stub
return member_list.size();
}
#Override
public HashMap<String, Object> getItem(int position) {
// TODO Auto-generated method stub
return member_list.get(position);
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
public void update(ArrayList<HashMap<String,Object>> obj) {
member_list2.clear();
member_list2.addAll(obj);
notifyDataSetChanged();
}
public final class DialogListItem{ // view holder
public TextView read_count;
public TextView nameView;
public TextView numberView;
public TextView statusView;
public ImageView thumb_image;
public TextView timeView;
public TextView senderView;
public ImageView tick;
//public BadgeView badge;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
int index;
if(sorting.equals("D")){
index = member_list.size()-position-1;
}else{
index = position;
}
View row = convertView;
DialogListItem dialogItem=null;
String textbuff_time = null;
String textbuff_mess = null;
String textbuff_sender = null;
if (convertView==null){
row=inflater.inflate(R.layout.dialog_list_single, null);
dialogItem=new DialogListItem();
dialogItem.read_count=(TextView)row.findViewById(R.id.readcount);
dialogItem.nameView=(TextView)row.findViewById(R.id.member_name);
dialogItem.numberView=(TextView)row.findViewById(R.id.tab2number);
dialogItem.statusView=(TextView)row.findViewById(R.id.tab2status);
dialogItem.thumb_image=(ImageView)row.findViewById(R.id.tab2image);
dialogItem.timeView=(TextView) row.findViewById(R.id.tab2date);
dialogItem.senderView=(TextView) row.findViewById(R.id.tab2sender);
dialogItem.tick = (ImageView) row.findViewById(R.id.tick);
row.setTag(dialogItem);
}
else{
dialogItem=(DialogListItem) row.getTag();
}
if (mSelectedItemsIds.get(position)) {
row.setBackgroundColor(context.getResources().getColor(R.color.item_selected));
} else {
row.setBackgroundColor(context.getResources().getColor(R.color.item_unselected));
}
HashMap<String,Object>items;
items=member_list.get(index);
dialogItem.nameView.setText((String)items.get(DBhelper.MEMBER_NAME));
dialogItem.nameView.setTypeface(null,Typeface.BOLD);
dialogItem.nameView.setSingleLine(true);
dialogItem.nameView.setMaxLines(1);
dialogItem.nameView.setEms(13);
dialogItem.nameView.setEllipsize(TruncateAt.END);
dialogItem.numberView.setText((String)items.get(DBhelper.MEMBER_NUMBER));
String textbuff=(String)items.get(DBhelper.MEMBER_LMESSAGE);
if (!TextUtils.isEmpty(textbuff)){
textbuff_time=textbuff.substring(0, 19);
textbuff_mess=textbuff.substring(20);
int bound=textbuff_mess.indexOf("½");
if(bound!=-1){
textbuff_sender=textbuff_mess.substring(0,bound);
textbuff_mess=textbuff_mess.substring(bound+2);
}
else
textbuff_sender="";
dialogItem.statusView.setText(textbuff_mess);
if (textbuff_sender.equals(context.getResources().getString(R.string.myself))) {
dialogItem.senderView.setVisibility(View.GONE);
dialogItem.tick.setVisibility(View.VISIBLE);
} else {
textbuff_sender = textbuff_sender + ": ";
dialogItem.senderView.setVisibility(View.VISIBLE);
dialogItem.senderView.setText(textbuff_sender);
dialogItem.tick.setVisibility(View.GONE);
}
try {
dialogItem.timeView.setText(Utility.relativeTime(row.getContext(), textbuff_time));
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
else{
dialogItem.statusView.setText("");
dialogItem.senderView.setText("");
dialogItem.timeView.setText("---");
}
dialogItem.statusView.setTextColor(Color.GRAY);
dialogItem.statusView.setTypeface(null,Typeface.NORMAL);
dialogItem.timeView.setTextColor(Color.GRAY);
dialogItem.timeView.setTypeface(null,Typeface.NORMAL);
dialogItem.senderView.setTextColor(Color.GRAY);
dialogItem.senderView.setTypeface(null,Typeface.NORMAL);
dialogItem.senderView.getPaint().setTextSkewX(-0.25f);
String sformat=" "+String.valueOf(items.get(DBhelper.MEMBER_SIZE))+" ";
dialogItem.read_count.setText(sformat);
int badge_number=(Integer)items.get(DBhelper.MEMBER_SIZE);
if(badge_number>0){
dialogItem.read_count.setVisibility(View.VISIBLE);
dialogItem.statusView.setTextColor(Color.BLACK);
dialogItem.statusView.setTypeface(null,Typeface.BOLD);
dialogItem.timeView.setTextColor(Color.BLACK);
dialogItem.timeView.setTypeface(null,Typeface.BOLD);
dialogItem.senderView.setTextColor(Color.BLACK);
dialogItem.senderView.setTypeface(null,Typeface.BOLD);
dialogItem.senderView.getPaint().setTextSkewX(-0.25f);
}
else{
dialogItem.read_count.setVisibility(View.GONE);
}
StringBuffer link=new StringBuffer(Register.get_current_server_address());
if(items.get(DBhelper.MEMBER_TYPE).equals(res.getString(R.string.broadcast_chat))){
dialogItem.nameView.setTextColor(row.getResources().getColor(R.color.tab4_title));
link.append("uniappSystemFile.asp");
link.append("?file=").append("broadcast.png");
//imageLoader.DisplayImage(link.toString(), dialogItem.thumb_image);
Picasso.with(context).load(link.toString()).transform(new CircleTransform()).resize(200,200).into(dialogItem.thumb_image);
dialogItem.read_count.setVisibility(View.GONE); // disable broadcast badge
}
Picasso.with(context).load(R.drawable.ic_contact).resize(200,200).into(dialogItem.thumb_image);
Picasso.with(context).load(R.drawable.ic_notif).resize(200, 200).into(dialogItem.thumb_image);
}else{
link2 = new IMService(context.getApplicationContext()).group_image_thumb_get(tab2.myphone, (String) items.get(DBhelper.MEMBER_NUMBER));
dialogItem.nameView.setTextColor(row.getResources().getColor(R.color.tab3_title));
//imageLoader.DisplayImage(link2, dialogItem.thumb_image);
Picasso.with(context).load(link2).transform(new CircleTransform()).resize(200, 200).placeholder(R.drawable.ic_group_circle_black_48dp).error(R.drawable.ic_group_circle_black_48dp).into(dialogItem.thumb_image);
}
}
public void setSearchPattern(String pattern) {
filterListByPattern(pattern.trim());
this.notifyDataSetChanged();
}
private void filterListByPattern(String searchPattern) {
member_list.clear();
for (HashMap<String,Object> info : member_list2) {
boolean add = true;
do {
if (searchPattern == null || searchPattern.equals("")) {
break;
}
if (info.get(DBhelper.MEMBER_NAME).toString().toLowerCase().contains(searchPattern)) {
break;
}
add = false;
} while (false);
if (add) {
member_list.add(info);
}
}
}
public void resetList() {
this.member_list2 = new ArrayList<HashMap<String,Object>>();
this.member_list2.addAll(this.member_list);
this.notifyDataSetChanged();
}
public void remove(Object object) {
member_list.remove(object);
notifyDataSetChanged();
}
public void toggleSelection(int position) {
selectView(position, !mSelectedItemsIds.get(position));
}
public void removeSelection() {
mSelectedItemsIds = new SparseBooleanArray();
selectedItemPosition = new ArrayList<>();
notifyDataSetChanged();
}
public void selectView(int position, boolean value) {
if (value) {
mSelectedItemsIds.put(position, value);
selectedItemPosition.add(position);
} else {
mSelectedItemsIds.delete(position);
selectedItemPosition.remove(selectedItemPosition.indexOf(position));
}
notifyDataSetChanged();
}
public int getSelectedCount() {
return mSelectedItemsIds.size();
}
public SparseBooleanArray getSelectedIds() {
return mSelectedItemsIds;
}
public ArrayList<Integer> getItemPosition() {
return selectedItemPosition;
}
}
So, my question is why would my adapter and listview show the old data after I return from other fragment to this fragment, and how to fix this?
P.S. please don't tell me to declare a new adapter like this
adapter = new MyAdapter(list);
adapter.notifyDataSetChanged();
I know it works, but it's not a good and appropriate approach since it's a heavy operation and you don't even need to use notifyDataSetChanged after declaring a new adapter.
Many thanks
Try putting setRetainInstance(true);
inside your fragment.
If above does not work then try with onSaveInstanceState() as below -
Declare at top, Parcelable state;
Save listview state, state = listview.onSaveInstanceState(); inside onpause() of fragment or manually while changing fragment.
Then inside onCreateView check state is null or not. If null then set adapter / get data, if not then set
listview.onRestoreInstanceState(state);
On the other hand, Each time you load fragment, ArrayList will start off empty. So you need to be careful to save data.
I try to use AsyncTaskLoader in Fragment that is a child of ViewPager. Below a code of my DayFragment:
public class DayFragment extends Fragment
implements LoaderManager.LoaderCallbacks<DayAdapter.DayItem[]> {
private static final int CONTENT_LOADER = 0;
private DayAdapter mAdapter = null;
private int mWeekNumber = 1;
private int mDayCode = 1;
private Table.Timetable mTimetable;
private RecyclerView mRVContent;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final MainActivity mainActivity = (MainActivity) getActivity();
View v = inflater.inflate(R.layout.content, container, false);
mRVContent = (RecyclerView) v.findViewById(R.id.rvContent);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(mainActivity);
mRVContent.setLayoutManager(layoutManager);
mAdapter = new DayAdapter(getActivity());
mRVContent.setAdapter(mAdapter);
//Initialize the cursor loader
getLoaderManager().initLoader(CONTENT_LOADER, null, this).forceLoad();
return v;
}
#Override
public Loader<DayAdapter.DayItem[]> onCreateLoader(final int id, Bundle args) {
if(CONTENT_LOADER == id) {
return new ContentLoader(getContext(), mWeekNumber, mDayCode, mTimetable);
}
return null;
}
#Override
public void onLoadFinished(Loader loader, DayAdapter.DayItem[] items) {
if(CONTENT_LOADER == loader.getId()) {
mAdapter.setIs24HourFormat(SettingsManager.is24HourFormat(getContext()));
mAdapter.clear();
for (DayAdapter.DayItem item : items) {
mAdapter.add(item);
}
mAdapter.notifyDataSetChanged();
if (items.length == 0) {
mRVContent.setBackgroundResource(R.drawable.bg_lesson_empty);
} else {
mRVContent.setBackgroundColor(0xFFFFFFFF);
}
}
}
#Override
public void onLoaderReset(Loader loader) {
}
private static final class ContentLoader extends AsyncTaskLoader<DayAdapter.DayItem[]> {
private final int mWeekNumber;
private final int mDayCode;
private final Table.Timetable mTimetable;
public ContentLoader(Context context, final int weekNumber, final int dayCode,
Table.Timetable timetable) {
super(context);
mWeekNumber = weekNumber;
mDayCode = dayCode;
mTimetable = timetable;
}
#Override
public DayAdapter.DayItem[] loadInBackground() {
DatabaseHandler db = new DatabaseHandler(getContext());
db.openReadable();
List<Table.Lesson> lessons = db.findLessons(mDayCode, mWeekNumber, mTimetable.getId());
DayAdapter.DayItem[] items = new DayAdapter.DayItem[lessons.size()];
for (int i = 0; i < items.length; ++i) {
Table.Lesson lesson = lessons.get(i);
Table.Subject subject = db.getSubject(lesson.getSubjectId());
Table.Teacher teacher = db.getTeacher(lesson.getTeacherId());
if (teacher == null) {
teacher = new Table.Teacher(""); //Empty name
}
items[i] = new DayAdapter.DayItem()
.setId(lesson.getId())
.setTitle(subject.getTitle())
.setSubtitle(teacher.getName()));
}
db.close();
return items;
}
}
}
PageAdapater
public class PageAdapter extends FragmentStatePagerAdapter {
public static final int PAGE_COUNT = 7;
private int mWeekNumber;
private final int[] mDayCodes;
private final String[] mDays;
private final DayFragment[] mFragments = new DayFragment[7];
private Table.Timetable mTimetable;
private boolean mIsRebuildMode = false;
public PageAdapter(Context context, FragmentManager fm,
Table.Timetable timetable, final int weekNumber) {
super(fm);
//Initialize class members
}
#Override
public Fragment getItem(int position) {
DayFragment dayFragment;
if (mFragments[position] == null) {
dayFragment = new DayFragment();
Bundle args = new Bundle();
args.putSerializable(Keys.TIMETABLE, mTimetable);
dayFragment.setArguments(args);
dayFragment.setWeekNumber(mWeekNumber);
dayFragment.setDayCode(mDayCodes[position]);
mFragments[position]= dayFragment;
} else {
dayFragment = mFragments[position];
}
return dayFragment;
}
#Override
public void restoreState(Parcelable arg0, ClassLoader arg1) {
//do nothing here! no call to super.restoreState(arg0, arg1);
}
public void setWeekNumber(final int weekNumber) {
mWeekNumber = weekNumber;
Arrays.fill(mFragments, null);
}
public void setIsRebuildMode(final boolean isRebuildMode) {
mIsRebuildMode = isRebuildMode;
}
#Override
public CharSequence getPageTitle(final int position) {
return mDays[position];
}
#Override
public int getCount() {
return PAGE_COUNT;
}
#Override
public int getItemPosition(Object object) {
if(mIsRebuildMode) {
return POSITION_NONE;
}
return super.getItemPosition(object);
}
}
But it doesn't call onLoadFinished method. I checked Log output... LoaderManager calls onCreateLoader but it never calls onLoadFinished except first run (when app started and ViewPager shows a first page (Fragment)). It's all! After if I switch a page to a next and a next and return to a first page LoaderManager doesn't call onLoadFinished for the first page too. But it creates loader calling onCreateLoader and resets loader calling onLoaderReset. Is it a joke from Google?
See fragment lifecycle. ViewPager don't re create fragment, just swipe them
-- Start ViewPager
: create
: createView
: start
: resume
not changed if you swipe fragments
--- sleep smartphone
: pause
: stop
--- wakeup smartphone
: start
: resume
: pause
--- Close ViewPager
: stop
: detach
I am using tabLayout which is attached with the viewPager. I have implemented viewPager Adapter using FragmentStatePager adapter, because the tabLayout list is big.
ViewPager creates a new instance of each fragment, and inside the fragment, i am using recyclerView to the data.
Now, before initiating the viewPager i am making a call to the server, and in success response, i am initiating viewPager for the first time. Then viewPager calls its getItem() callback, where it gets the data for the first position initialises the fragment and it's recyclerView.
It also call getItem() for the next position as i have set the offScreenLimit() to 2, which is fine and working well.
The problem is when it calls getItem() and creates the fragment, at that time, i am checking if i have the data, if not, then i am making a callback to get data from server.
And if user visits that position, i want to updated the fragment recyclerView.
Here, i have passed the reference of the main object in the fragment, so on success of request, it updates the main object, and the updated object will be present inside the fragment list.
Since, it's an asynchronous call, i want to show a loader and then update the fragment.
Here is where my problem lies. I am not able to update the fragment recyclerView. It's updating but taking time.
I had tried using return POSITION_NONE which worked fine, but it's not a good approach as it creates a new fragment every time.
This is my viewPagerAdapter.
public class ShowTimeViewPageAdapter extends FragmentStatePagerAdapter {
private static final String TAG = ShowTimeViewPageAdapter.class.getSimpleName();
private Context mContext;
private List<String> mDateStringList;
private FragmentManager fragmentManager;
private IShowTimeActivity mIShowTimeActivity;
private List<String> mDateCodes;
private LinkedHashMap<String, List<Venue>> mVenueHashMap;
public ShowTimeViewPageAdapter(FragmentManager fm, Context context, IShowTimeActivity showTimeActivity, List<String> createdDates, List<String> dateCodes, LinkedHashMap<String, List<Venue>> venueHashMap) {
super(fm);
this.mContext = context;
this.mIShowTimeActivity = showTimeActivity;
this.fragmentManager = fm;
this.mDateCodes = dateCodes;
this.mVenueHashMap = venueHashMap;
this.mDateStringList = createdDates;
}
private String getDateCode(int pos) {
String dateCode = null;
try {
dateCode = mDateCodes.get(pos);
} catch (IndexOutOfBoundsException e) {
Logger.d(TAG, "Index out of bound");
}
return dateCode;
}
private List<Venue> getVenuesList(String dateCode) {
return mVenueHashMap.get(dateCode);
}
#Override
public Fragment getItem(int position) {
if (getDateCode(position) != null) {
if (getVenuesList(getDateCode(position)) == null) {
if(position!=0){
mIShowTimeActivity.requestForTheVenueListByDateCode(getDateCode(position), position);
}
}
}
ShowTimeFragment showTimeFragment = ShowTimeFragment.newInstance(mDateStringList.get(position).split(";")[2]);
fragmentManager.beginTransaction().add(showTimeFragment,""+position);
return showTimeFragment;
}
#Override
public int getCount() {
return mDateStringList.size();
}
public View getTabView(int position) {
String[] dateStr = mDateStringList.get(position).split(";");
LayoutInflater layoutInflater = LayoutInflater.from(mContext);
View tabView = layoutInflater.inflate(R.layout.show_time_tab_layout, null, false);
TextViewRoboto day = (TextViewRoboto) tabView.findViewById(R.id.show_time_tab_day);
TextViewRoboto date = (TextViewRoboto) tabView.findViewById(R.id.show_time_tab_date);
day.setText(dateStr[0]);
date.setText(dateStr[1]);
return tabView;
}
}
And this is the Fragment.
public class ShowTimeFragment extends Fragment {
#Bind(R.id.show_time_fragment_recycler_view) RecyclerView mShowTimeRecyclerView;
#Bind(R.id.show_time_fragment_no_data_text_view) TextViewRoboto mShowTimeNoDataTextView;
private static LinkedHashMap<String, List<Venue>> mVenueList = ShowTimeActivity.mVenueHashMap;
private ShowTimeRecyclerViewAdapter mShowTimeRecyclerViewAdapter;
private static final String KEY_CODE = "date_key";
public ShowTimeFragment() {
}
public static ShowTimeFragment newInstance(String dateCode) {
Bundle bundle = new Bundle();
bundle.putString(KEY_CODE, dateCode);
ShowTimeFragment showTimeFragment = new ShowTimeFragment();
showTimeFragment.setArguments(bundle);
return showTimeFragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.show_time_fragment, container, false);
ButterKnife.bind(this, view);
String code = getArguments().getString(KEY_CODE);
List<Venue> venueList = mVenueList.get(code);
if (venueList != null && venueList.size() > 0) {
mShowTimeRecyclerView.setVisibility(View.VISIBLE);
mShowTimeNoDataTextView.setVisibility(View.GONE);
mShowTimeRecyclerViewAdapter = new ShowTimeRecyclerViewAdapter(venueList, getContext());
mShowTimeRecyclerView.setAdapter(mShowTimeRecyclerViewAdapter);
CustomLinearLayoutManager cl = new CustomLinearLayoutManager(getActivity(), 1, false);
mShowTimeRecyclerView.setLayoutManager(cl);
RecyclerView.OnItemTouchListener disabler = new RecyclerViewDisabler();
mShowTimeRecyclerView.addOnItemTouchListener(disabler); // disables scrolling
} else {
mShowTimeNoDataTextView.setVisibility(View.VISIBLE);
mShowTimeRecyclerView.setVisibility(View.GONE);
mShowTimeNoDataTextView.setText("NO Data Available");
}
return view;
}
public class RecyclerViewDisabler implements RecyclerView.OnItemTouchListener {
#Override
public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) {
return true;
}
#Override
public void onTouchEvent(RecyclerView rv, MotionEvent e) {
}
#Override
public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {
}
}
protected void addFragment(int containerViewId, Fragment fragment, String fragmentTag) {
getActivity().getSupportFragmentManager().beginTransaction().add(containerViewId, fragment, fragmentTag).disallowAddToBackStack().commit();
}
public void onDestroyView() {
super.onDestroyView();
}
}
In the above fragment
private static LinkedHashMap<String, List<Venue>> mVenueList = ShowTimeActivity.mVenueHashMap;
this hashMap is the reference to the original hashMap, which is updated on each request.
Any kind of help or suggestions would be appreciated.
Hi i got the viewpager :contains one fragment with two different views inside [A] and [B]. both views contain a list view. when I scroll , list view [A] and switch to second fragment I want list view [B] also be scrolled with the same amount. I've searched that I can set onTouchListener to the listview.please find below the code i used.
viewpager adapter
public class ViewPagerAdapter extends FragmentStatePagerAdapter implements
CurrencyScrollListener {
private String nBankName;
private List<Currency> list;
private String mycode;
private CurrencyViewPager[] mFragments = new CurrencyViewPager[2];
private int mCurrentScrollPosition;
#Override
public int getItemPosition(Object object) {
// TODO Auto-generated method stub
return super.getItemPosition(object);
}
public CurrencyViewPager getCurrencyFragment(int index) {
CurrencyViewPager pager = mFragments[index];
CurrencyViewPager other = mFragments[1-index];
if (pager == null) {
if (index == 0) {
pager = new CurrencyViewPager(list, nBankName, true, mycode,
this, 0);
} else {
pager = new CurrencyViewPager(list, nBankName, false, mycode,
this, 1);
}
mFragments[index] = pager;
}
if(other!=null && other.getCurrentPosition() != pager.getCurrentPosition()) {
pager.scrollTo( other.getCurrentPosition() );
}
return pager;
}
public ViewPagerAdapter(FragmentManager fm, List<Currency> currencyList,
String name, String code) {
super(fm);
this.list = currencyList;
this.nBankName = name;
this.mycode = code;
}
#Override
public Fragment getItem(int item) {
Log.i("ViewPagerAdapter","Currency Fragment #"+item);
return getCurrencyFragment(item);
}
#Override
public int getCount() {
return 2;
}
}
}
And single fragment containing list view
public class CurrencyViewPager extends BaseFragment {
private ListView mcurrencyListview;
private GeoCurrencyService mCurrency = GeoCurrencyService.getInstance();
ButtonPressListener buttonListener;
private CurrencyAdapter mCurrencyAdapter;
private String bankName;
private boolean checkFlag;
private ProgressBar mCurrencyProgress;
private TextView mCurrencyLoading;
private List<Currency> mList;
private String recCode;
private static int Firstposition;
private final CurrencyScrollListener listener;
private final int mListViewIndex;
// constructor
public CurrencyViewPager(List<Currency> myList, String name, boolean flag,String code, CurrencyScrollListener listener, int listViewIndex) {
super();
this.mList = myList;
this.bankName = name;
this.checkFlag = flag;
this.recCode = code;
this.listener = listener;
this.mListViewIndex = listViewIndex;
}
// interface
public interface ButtonPressListener {
public void onListItemPressed(Currency object, String name,String code);
}
// attach on listener
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
buttonListener = (ButtonPressListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement onButtonPressed");
}
}
// creating the main View.
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
View view = inflater.inflate(R.layout.listbuy, container, false);
mcurrencyListview = (ListView) view.findViewById(R.id.BuyList);
mCurrencyAdapter = new CurrencyAdapter(getActivity(),
R.layout.currency_row, mList, checkFlag, getLanguage());
mcurrencyListview.setAdapter(mCurrencyAdapter);
// calling method getCurrency which take bank code as a parameter
/*getCurrency(code,null);*/
// reference to the list view of the corresponding layout
mcurrencyListview.setOnItemClickListener(new OnItemClickListener() {
// onClick on the List item
#Override
public void onItemClick(AdapterView<?> arg0, View arg1,
int position, long arg3) {
// getting Currency object according to the position
Currency currencyObject = mCurrencyAdapter.getItem(position);
// sending the object to the mainActivity
buttonListener.onListItemPressed(currencyObject, bankName,recCode);
}
});
return view;
}
}
First off, you should be using FragmentPagerAdapter instead of FragmentStatePagerAdapter (Look here for more information).
Now, to the question at hand.
Use the following to get the current position of ListView [A]
int index = mListA.getFirstVisiblePosition();
View v = mListA.getChildAt(0);
int top = (v == null) ? 0 : v.getTop();
And use this to set the position of ListView [B]:
mListB.setSelectionFromTop(index, top);
Look at this SO post for more information.