Switch between different ViewPagers - android

I am trying to switch between different ViewPagers (using e.g. a button). It is basically a small tool to optically compare different versions of images. Right now I have only implemented a single ViewPager nested in a RelativeLayout (need the layout for something else). The content is filled by a custom PagerAdapter.
Any ideas on how to change forth and back between multiple ViewPagers?
MainActivity.java
public class MainActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ViewPager mViewPager = (ViewPager) findViewById(R.id.view_pager);
mViewPager.setAdapter(new SheetPagerAdapter());
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
SheetPagerAdapter.java
public class SheetPagerAdapter extends PagerAdapter {
#Override
public int getCount() {
return 4;
}
#Override
public Object instantiateItem(ViewGroup container, int position) {
SheetView sheetView = new SheetView(container.getContext(), position);
container.addView(sheetView, LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
return sheetView;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
}
SheetView.java
public class SheetView extends RelativeLayout {
private final String[] images = {
"page01.jpg",
"page02.jpg",
"page03.jpg",
"page04.jpg"
};
private SubsamplingScaleImageView scaleImageView;
public SheetView(Context context, int page) {
super(context);
scaleImageView = new SubsamplingScaleImageView(context);
this.addView(scaleImageView, RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);
scaleImageView.setImage(ImageSource.asset(images[page]));
}
}

I finally ended up using a FrameLayout with multiple ViewPagers as child elements.
Only the "active" Layout is set visible:
public class MainActivity extends ActionBarActivity {
private ArrayList<ViewPager> viewPagerList = new ArrayList<>();
private final int NUM_LAYERS = 10;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FrameLayout container = (FrameLayout) findViewById(R.id.frame_container);
// Add ViewPagers and fill ArrayList
for(int i = 0; i < NUM_LAYERS; i++) {
ViewPager vp = new ViewPager(this);
vp.setVisibility(View.INVISIBLE); // Make invisible
viewPagerList.add(vp);
container.addView(vp);
}
// Make first ViewPager visible
viewPagerList.get(0).setVisibility(View.VISIBLE);
}
// Switch to other ViewPager
public void setViewPager(int number) {
for (ViewPager vp : viewPagerList) {
vp.setVisibility(View.INVISIBLE);
}
viewPagerList.get(number).setVisibility(View.VISIBLE);
}
}

Related

Adapter is multiplying with the same data android

I have a SwitchTabActivty with 4 items. In my case, I use the second item to get some data from the web through a recyclerview. The problem is that when I press the fourth item (it contains a button that's starting an activity) and I go back to my second tab , my recycler view is multiplied with the same data again.
Switchtabactivity :
public class SwitchTabActivity extends AppCompatActivity {
private SectionsPagerAdapter mSectionsPagerAdapter;
private ViewPager mViewPager;
private boolean pressToExit = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_switch_tab);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// Create the adapter that will return a fragment for each of the three
// primary sections of the activity.
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(mViewPager);
tabLayout.getTabAt(0).setIcon(R.drawable.weather_tab);
tabLayout.getTabAt(1).setIcon(R.drawable.events);
tabLayout.getTabAt(2).setIcon(R.drawable.details_tab);
tabLayout.getTabAt(3).setIcon(R.drawable.settings_tab);
setColorTab(tabLayout);
}
private void setColorTab(TabLayout tab) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
tab.setTabTextColors(getResources().getColorStateList(R.color.tab_colors, null));
} else {
tab.setTabTextColors(getResources().getColorStateList(R.color.tab_colors));
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
}
#Override
public void onBackPressed() {
if (!pressToExit) {
Toast.makeText(this, "Press back again to exit.", Toast.LENGTH_SHORT).show();
pressToExit = true;
} else {
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
}
#Override
public void onResume() {
super.onResume();
pressToExit = false;
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_switch_tab, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return WeatherFragment.newInstance(position);
case 1:
return EventFragment.newInstance(position);
case 2:
return OwnEventFragment.newInstance(position);
case 3:
return SettingsFragment.newInstance(position);
}
return null;
}
#Override
public int getCount() {
return 4;
}
#Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "Weather";
case 1:
return "Events";
case 2:
return "My Events";
case 3:
return "Settings";
}
return null;
}
}
EventFragment :
public class EventFragment extends Fragment implements EventResponse {
private String latitude, longitude;
private static final String ARG_SECTION_NUMBER = "section_number";
private RecyclerView eventList;
private EventAdapter adapter;
private TextView ifNullEvents;
private final ArrayList<EventData> eventsData = new ArrayList<>();
private UserDataBase db;
private List<String> latLonList;
private ProgressBar progressBar;
public EventFragment() {
}
public static EventFragment newInstance(int sectionNumber) {
EventFragment fragment = new EventFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.event_fragment, container, false);
initView(rootView);
db = new UserDataBase(getContext());
checkLocationChanged();
latLonList = db.getLatLon();
latitude = latLonList.get(0);
longitude = latLonList.get(1);
String EVENT_BRITE_URL_PARSE = "MY_URL";
String EVENT_BRITE_TOKEN = "MY_TOKEN";
new EventBriteApi(this, getContext()).execute(EVENT_BRITE_URL_PARSE + EVENT_BRITE_TOKEN);
setupRecyclerView();
setLocationMessage();
return rootView;
}
private void initView(View view) {
eventList = (RecyclerView) view.findViewById(R.id.event_recycler_view);
ifNullEvents = (TextView) view.findViewById(R.id.text_null_location);
progressBar = (ProgressBar) view.findViewById(R.id.progress_bar_event);
}
private void checkLocationChanged() {
if (WePrefs.isLocationChanged) {
eventsData.clear();
ifNullEvents.setText(getResources().getString(R.string.waiting_for_data));
ifNullEvents.setVisibility(View.VISIBLE);
progressBar.setVisibility(View.VISIBLE);
WePrefs.setIsLocationChanged(false);
} else {
progressBar.setVisibility(View.GONE);
ifNullEvents.setVisibility(View.GONE);
}
if (WePrefs.isNullEventLocation) {
ifNullEvents.setText(getResources().getString(R.string.no_events_found));
ifNullEvents.setVisibility(View.VISIBLE);
progressBar.setVisibility(View.INVISIBLE);
WePrefs.setIsNullEventLocation(false);
}
}
private void setupRecyclerView() {
eventList.setHasFixedSize(true);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
eventList.setLayoutManager(linearLayoutManager);
adapter = new EventAdapter(getActivity(), eventsData);
adapter.setHasStableIds(true);
eventList.setAdapter(adapter);
}
#Override
public void onResume() {
checkLocationChanged();
setLocationMessage();
super.onResume();
}
private void setLocationMessage() {
if (eventsData.isEmpty()) {
ifNullEvents.setVisibility(View.VISIBLE);
progressBar.setVisibility(View.VISIBLE);
} else {
ifNullEvents.setVisibility(View.GONE);
progressBar.setVisibility(View.GONE);
}
progressBar.setVisibility(View.GONE);
}
#Override
public void getArray(ArrayList<EventData> data) {
eventsData.clear();
eventsData.addAll(new ArrayList<>(new LinkedHashSet<>(data)));
}
}
Adapter :
ublic class EventAdapter extends RecyclerView.Adapter<EventAdapter.EventHolder> {
ArrayList<EventData> data;
Context context;
public EventAdapter(Context context, ArrayList<EventData> events) {
this.context = context;
data = events;
}
#Override
public EventHolder onCreateViewHolder(ViewGroup parent, int viewType) {
RelativeLayout layout = (RelativeLayout) LayoutInflater.from(parent.getContext()).inflate(R.layout.single_event_view, parent, false);
return new EventAdapter.EventHolder(layout);
}
#Override
public void onBindViewHolder(EventHolder holder, int position) {
holder.eventName.setText(data.get(position).getEventName());
if (data.get(position).getEventImageUrl() != null) {
Picasso.with(context).load(data.get(position).getEventImageUrl()).into(holder.eventPic);
} else {
holder.eventPic.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.no_image));
}
}
#Override
public int getItemCount() {
return data.size();
}
public class EventHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
TextView eventName;
ImageView eventPic;
RelativeLayout layout;
public EventHolder(View itemView) {
super(itemView);
eventName = (TextView) itemView.findViewById(R.id.event_name);
eventPic = (ImageView) itemView.findViewById(R.id.event_image);
layout = (RelativeLayout) itemView.findViewById(R.id.event_layout);
layout.setOnClickListener(this);
}
#Override
public void onClick(View view) {
//context.startActivity(new Intent(context, WebViewActivity.class));
}
}
}
Those are some of my java classes that I use for this kind of thing.
Anyway, another problem is that, when I change the location ( to receive my events) I must go to another tab and after that to come back to see my events list ( I think it needs to recreate the view ) so , because of that I called onResume, but it does not help.

Fragment is showing but not attached to activity

Hi i am working in an app, in which:
View pager is there on an activity.
On that view pager i am showing 2 fragments(frag1 and frag2).
on button click on frag1 we have added one more fragment(lets say frag3).
and on back press on frag3 i come back on frag1.
Issue:
the issue is when i come back to frag1 from frag3 on back press, sometimes frag1 is not attached to the activity.
i am not able to figure out how this is happening.
if this is happening then what is the solution so i can stop activity to detach the frag1 or re-initialize the frag1 again.
Please help.
This code may help you
public class PageAdapter extends FragmentPagerAdapter implements IconPagerAdapter {
protected static final int[] PAGER = new int[] {
R.drawable.image1,
R.drawable.image2,
R.drawable.image3,
R.drawable.image4
};
private int mCount = PAGER.length;
public PagerFragmentAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
return new PagerFragment(PAGER[position]);
}
#Override
public int getIconResId(int index) {
return ICONS[index % PAGER.length];
}
#Override
public int getCount() {
return mCount;
}
public void setCount(int count) {
if (count > 0 && count <= 10) {
mCount = count;
notifyDataSetChanged();
}
}
}
Defining Fragments
public final class PagerFragment extends Fragment {
private static final String KEY_CONTENT = "PagerFragment:Content";
int imageSource;
public PagerFragment(int imageSource) {
this.imageSource = imageSource;
}
public PagerFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if ((savedInstanceState != null) && savedInstanceState.containsKey(KEY_CONTENT)) {
imageSource = savedInstanceState.getInt(KEY_CONTENT);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
ViewGroup root = (ViewGroup) inflater.inflate(R.layout.indicatorpage, null);
ImageView image = (ImageView) root.findViewById(R.id.pagerImage);
image.setImageResource(imageSource);
setRetainInstance(true);
return root;
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt(KEY_CONTENT, imageSource);
}
}
MainActivity Class
public class MainActivity extends FragmentActivity {
PagerFragmentAdapter mAdapter;
ViewPager mPager;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mAdapter = new PagerFragmentAdapter(getSupportFragmentManager());
mPager = (ViewPager) findViewById(R.id.pager);
mPager.setAdapter(mAdapter);
mPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
System.out.println("selected page is :" + position);
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
CirclePageIndicator mIndicator = (CirclePageIndicator) findViewById(R.id.indicator);
mIndicator.setViewPager(mPager);
final float density = getResources().getDisplayMetrics().density;
mIndicator.setRadius(7 * density);
mIndicator.setPageColor(0x00000000);
mIndicator.setFillColor(0xFFFFFFFF);
mIndicator.setStrokeColor(0xFFFFFFFF);
mIndicator.setStrokeWidth(1 * density);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}

FragmentStatePagerAdapter and ViewPager: Fragments instantiate out of order

I am trying to use FragmentStatePagerAdapter with ViewPager to achieve a sequential slide scroll view (similar to most pdf readers). However, while running the code, the following is happening:
When the activity becomes visible, the first page is instantiated with a different (2nd) page's value. However, when scrolled to some other page and then back to page 1, the page displays default text from layout file.
Only 2nd and 2nd to last pages instantiate with the passed value (that too with values from other pages, not their own). Rest of the pages display default text from layout file.
On debugging, I noticed that the index/currentItemNumber changes when ViewPager.populate() calls ViewPager.addNewItem(). Ever more strange is the fact that setText() is called on the TextView (part of fragment layout), but text does not change from the default text.
Am I missing something?
Here is the code below:
MainActivity.java
public class MainActivity extends ActionBarActivity implements View.OnClickListener {
private ViewPager mPager;
private Button mButtonFirst;
private Button mButtonPrev;
private Button mButtonGoTo;
private Button mButtonNext;
private Button mButtonLast;
private TextView mPageCount;
private EditText mPageNumber;
private TextView mError;
private int mNumScreens;
private int mCurrScreen;
private MyPagerAdapter mMyPagerAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setUpViews();
setUpListeners();
setUpPager();
}
private void setUpViews() {
mPager = (ViewPager) findViewById(R.id.my_pager);
// Get other view handles...
mError = (TextView) findViewById(R.id.error_details);
}
private void setUpListeners() {
// Set this class as click handler for all buttons
}
private void setUpPager() {
String[] strings = new String[] {
"1",
"2",
"3",
"4",
"5",
"6"
};
// Success!
// Set adapter and update views
mMyPagerAdapter = new MyPagerAdapter(getSupportFragmentManager(), strings);
mPager.setAdapter(mMyPagerAdapter);
mNumScreens = strings.length;
mPageCount.setText("/" + Integer.toString(mNumScreens));
mCurrScreen = -1;
GoToScreen(1);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
// Handle options
return super.onOptionsItemSelected(item);
}
#Override
public void onClick(View v) {
switch(v.getId()) {
case R.id.button_first:
GoToScreen(1);
break;
case R.id.button_prev:
GoToScreen(mCurrScreen - 1);
break;
case R.id.button_goto:
{
int screen;
boolean reset = false;
try {
screen = Integer.parseInt(mPageNumber.getText().toString());
reset = !SetToScreen(screen);
} catch (NumberFormatException e) {
e.printStackTrace();
reset = true;
}
if(reset) {
mPageNumber.setText(Integer.toString(mCurrScreen));
}
}
break;
case R.id.button_next:
GoToScreen(mCurrScreen + 1);
break;
case R.id.button_last:
GoToScreen(mNumScreens);
break;
}
}
private void GoToScreen(int screen) {
if(SetToScreen(screen)) {
mPageNumber.setText(Integer.toString(mCurrScreen));
}
}
private boolean SetToScreen(int screen) {
// Switch to a valid screen
if(screen >= 1 && screen <= mNumScreens && mCurrScreen != screen) {
mPager.setCurrentItem(screen - 1, false);
// Handle button visibility
// Update current screen
mCurrScreen = screen;
return true;
}
return false;
}
MyPagerAdapter.java
public class MyPagerAdapter extends FragmentStatePagerAdapter {
private final String[] mStrings;
public MyPagerAdapter(FragmentManager fm, String[] strings) {
super(fm);
mStrings = strings;
}
#Override
public int getCount() {
return mStrings.length;
}
#Override
public Fragment getItem(int position) {
return ScreenFragment.newInstance(mStrings[position]);
}
}
ScreenFragment.java
public class ScreenFragment extends Fragment {
private static final String ARG_SCREEN_STRING= "screen_string";
private String mScreenInfo;
private TextView mStatementLabel;
public static ScreenFragment newInstance(String screenString) {
ScreenFragment fragment = new ScreenFragment();
Bundle args = new Bundle();
args.putString(ARG_SCREEN_STRING, screenString);
fragment.setArguments(args);
return fragment;
}
public ScreenFragment() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments() != null) {
mScreenInfo = getArguments().getString(ARG_SCREEN_STRING);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_screen, container, false);
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setUpViews();
setUpFields();
}
private void setUpFields() {
mStatementLabel.setText(mScreenInfo);
}
private void setUpViews() {
mStatementLabel = (TextView) getActivity().findViewById(R.id.qnr_screen_statement);
}
}
The problem was solved when I moved calls to setUpViews() and setUpFields() to onCreateView() from onActivityCreated(), with little modifications. This is how the new onCreateView() looks like (I moved the content of the above mentioned functions here)
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v = inflater.inflate(R.layout.fragment_screen, container, false);
mStatementLabel = (TextView) v.findViewById(R.id.qnr_screen_statement);
mStatementLabel.setText(mScreenInfo);
return v;
}
I am yet to figure out why that was causing the problem. Will update if I find anything.

Android : FragmentList items repeating themselves

I have created a ViewPager in my MainActivity that contains 5 tabs. In the first tab I have put a ListView in order to display some items. The problem is that whenever I swipe to a different tab and then return to the first, the items in the list are duplicated (i.e list contains A-B-C and then A-B-C-A-B-C). The odd thing is that this occurs only when I swipe further than the second tab. Here is my code :
MainActivity :
public class MainActivity extends FragmentActivity implements ActionBar.TabListener {
private ViewPager viewPager;
private TabsPagerAdapter mAdapter;
private ActionBar actionBar;
//private String[] tabs = { "Mixed", "Videos", "Audio", "Text", "Picture" };
final int[] ICONS = new int[] {
R.drawable.mixed,
R.drawable.video,
R.drawable.audio,
R.drawable.note,
R.drawable.photo
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewPager = (ViewPager) findViewById(R.id.pager);
actionBar = getActionBar();
mAdapter = new TabsPagerAdapter(getSupportFragmentManager());
viewPager.setAdapter(mAdapter);
actionBar.setHomeButtonEnabled(false);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
// Adding Tabs
for (int i=0;i<ICONS.length;i++) {
actionBar.addTab(actionBar.newTab().setIcon(MainActivity.this.getResources().getDrawable(ICONS[i]))
.setTabListener(this));
}
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageSelected(int position) {
// on changing the page
// make respected tab selected
actionBar.setSelectedNavigationItem(position);
}
#Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
#Override
public void onPageScrollStateChanged(int arg0) {
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {
}
#Override
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {
}
public class TabsPagerAdapter extends FragmentPagerAdapter {
public TabsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public android.support.v4.app.Fragment getItem(int index) {
switch (index) {
case 0:
return MixedFragment.newInstance();
case 1:
return new VideosFragment();
case 2:
return new AudioFragment();
case 3:
return new TextFragment();
case 4:
return new PictureFragment();
}
return null;
}
#Override
public int getCount() {
// get item count - equal to number of tabs
return 5;
}
}
}
Fragment Class :
public class MixedFragment extends ListFragment implements AdapterView.OnItemClickListener {
ListView mixed;
JSONArray videos =null;
List<NameValuePair> row;
ArrayAdapter<VideoRow> adapter;
private List<VideoRow> listRow = new ArrayList<>();
private List<String> pathList = new ArrayList<>();
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.mixed, container, false);
mixed = (ListView) v.findViewById(android.R.id.list);
row = new ArrayList<>();
// mixed.setOnItemClickListener(this);
new populateLists().execute();
return v;
}
public static MixedFragment newInstance(){
MixedFragment mx = new MixedFragment();
return mx;
}
public void onItemClick(AdapterView<?> l, View v, int position, long id) {
String sendPath = pathList.get(position);
Intent start = new Intent(getActivity(), PlayVideo.class);
start.putExtra("Path", sendPath);
startActivity(start);
}
class populateLists extends AsyncTask<String,String,String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(String... params) {
JSONParser jParser = new JSONParser();
JSONObject obj = jParser.makeHttpRequest(Config.URL_Populate,"GET",row);
try {
// Checking for SUCCESS TAG
int success = obj.getInt("success");
if (success == 1) {
// videos found
// Getting Array of videos
videos = obj.getJSONArray("video");
// looping through All videos
for (int i = 0; i < videos.length(); i++) {
JSONObject c = videos.getJSONObject(i);
// Storing each json item in variable
String path = Config.URL_2server+c.getString("path");
String thumbnail = c.getString("thumbnail");
String title = c.getString("title");
String name =c.getString("name");
title = "\""+title+"\"";
byte[] bytes = Base64.decode(thumbnail,Base64.DEFAULT);
Bitmap thumb = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
pathList.add(path);
listRow.add(new VideoRow(path,thumb, name, title));
}
}
adapter = new MyListAdapterFrag(getActivity(), R.layout.enlarged_list_row, listRow,1);
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(String file_url) {
mixed.setAdapter(adapter);
}
}
}
ListAdapter :
public class MyListAdapterFrag extends ArrayAdapter<VideoRow> {
List<VideoRow> lRow;
Bitmap myThumb;
int activity;
public MyListAdapterFrag(Context context, int resource, List<VideoRow> listRow, int i) {
super(context, resource, listRow);
lRow=listRow;
activity=i;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
View row = convertView;
if (row == null) {
LayoutInflater inflater = LayoutInflater.from(getContext());
if (activity == 1) {
row = inflater.inflate(R.layout.list_row, parent, false);
} else if (activity == 2) {
row = inflater.inflate(R.layout.enlarged_list_row, parent, false);
}
viewHolder = new ViewHolder();
viewHolder.txtName = (TextView) row.findViewById(R.id.name);
viewHolder.txtTitle = (TextView) row.findViewById(R.id.title);
viewHolder.imageThumb = (ImageView) row.findViewById(R.id.thumbnail);
row.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) row.getTag();
}
VideoRow thisRow = lRow.get(position);
viewHolder.txtName.setText(thisRow.getName());
Bitmap thumb = thisRow.getThumb();
if (activity == 1) {
myThumb = Bitmap.createScaledBitmap(thumb, 40, 40, true);
} else if (activity == 2) {
myThumb = Bitmap.createScaledBitmap(thumb, 60, 60, true);
}
viewHolder.imageThumb.setImageBitmap(myThumb);
viewHolder.txtTitle.setText(thisRow.getTitle());
return row;
}
private static class ViewHolder {
ImageView imageThumb;
TextView txtTitle;
TextView txtName;
}
}
So, do you guys have any idea what causes this bug ?
The problem is caused by the fact that your fragment gets reinitialized when the ViewPager goes past a certain point.
This is called the off screen page limit.
This means, that once your first Fragment is past the limit, when you return to it, the onCreateView function will be called again. You need to check whether the populateLists AsyncTask really needs to fire or not.
Alternatively, you can increase your off screen page limit, to retain all your Fragments.
When you move to another fragment in ViewPager, the previous fragment's view might be destroyed (I think the default size is two fragments e.g. when fragment#2 gets on screen, fragment#0 is destroyed). When you go back, it's recreated. Every time you return to MixedFragment, its onCreateView method is called but you never clear the adapter when it's destroyed. That's why you see duplicates.
So you can just clear the adapter when its view is destroyed:
#Override
public void onDestroyView() {
super.onDestroyView();
adapter.clear();
}

Pager adapter with private methods without fragments in android

Is it possible to user View pager without fragments. I google it, and all examples use fragments for view pager. I want to pager load only one item from my list, so I want to ask is it possible. Here is my code for main activity, and I want to use UpdateDisplay for viewpager. Any suggestions.
public class MainActivity extends Activity implements OnClickListener{
private Button prev, next;
private TextView tv;
private int number = 0;
private ArrayList<Integer> numbers;
private ViewPager pager;
private MyPagerAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
prev = (Button) findViewById(R.id.prevButton);
prev.setOnClickListener(this);
next = (Button) findViewById(R.id.nextButton);
next.setOnClickListener(this);
numbers = new ArrayList<Integer>();
for (int i=0;i<5;i++){
numbers.add(i);
Log.i("Sljedece elemente dodaje u listu", String.valueOf(i));
}
tv = (TextView) findViewById(R.id.rezultatTextView);
pager = (ViewPager) findViewById(R.id.pager);
adapter = new MyPagerAdapter();
pager.setAdapter(adapter);
updateDIsplay(number);
}
#Override
public void onClick(View v) {
switch(v.getId()){
case R.id.prevButton:
number--;
if (number==-1){
number = 4;
}
updateDIsplay(number);
break;
case R.id.nextButton:
number++;
if (number==5){
number = 0;
}
updateDIsplay(number);
break;
}
}
private void updateDIsplay(int z){
tv.setText(String.valueOf(numbers.get(z)));
}
private class MyPagerAdapter extends PagerAdapter{
#Override
public int getCount() {
return numbers.size();
}
#Override
public boolean isViewFromObject(View arg0, Object arg1) {
return false;
}
}
}
yes it possible. Use a PageAdapter. When instantiateItem is called, you can inflate/instantiate your view, and this to the container. E.g:
private class MyPagerAdapter extends PagerAdapter {
#Override
public Object instantiateItem(ViewGroup container, int position) {
TextView view = new TextView(PagerActivity.this);
view.setText("Item "+position);
view.setGravity(Gravity.CENTER);
view.setBackgroundColor(Color.argb(255, position * 50, position * 10, position * 50));
container.addView(view);
return view;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View)object);
}
#Override
public int getCount() {
return 5;
}
#Override
public boolean isViewFromObject(View view, Object object) {
return (view == object);
}
}

Categories

Resources