Issue with doing fragment transaction inside a getview of baseadapter? - android

Have a Linearlayout inside to that having 3 different framelayout. In that frame layout am adding the fragments dynamically inside the adaper getview. Initially the adapter getview gets called twice. Then later it called once for every flip. Have added the flip view functionality along with that. In that for first screen before any flip, the dynamic fragments are not getting added to the main view. But for the later flipped screens it's getting added properly.
Please help me on this.
Thanks in advance.
public class MainActivity extends Activity {
private FragmentTransaction fragMentTra = null;
protected FlipViewController flipView;
private LayoutInflater inflater;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
flipView = new FlipViewController(this);
flipView.setAdapter(new BaseAdapter() {
public int getCount() {
return 2;
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
#SuppressLint("NewApi")
public View getView(int position, View convertView, ViewGroup parent) {
View layout = convertView;
if (convertView == null) {
inflater = LayoutInflater.from(parent.getContext());
layout = inflater.inflate(R.layout.activity_main, null);
AphidLog.d("created new view from adapter: %d", position);
}
NewsFragment[] newsFragment_obj = new NewsFragment[GlobalValues.titile.length];
fragMentTra = getFragmentManager().beginTransaction();
for (int i = 0; i < GlobalValues.titile.length; i++) {
newsFragment_obj[i] = new NewsFragment(
GlobalValues.titile[i], GlobalValues.content[i]);
AphidLog.d("Array Loc: %d", i);
}
fragMentTra.add(R.id.fragment_container1, newsFragment_obj[0],
"Fragment1");
fragMentTra.add(R.id.fragment_container2, newsFragment_obj[1],
"Fragment2");
fragMentTra.add(R.id.fragment_container3, newsFragment_obj[2],
"Fragment3");
fragMentTra.commit();
return layout;
}
});
setContentView(flipView);
}

Related

Cannot update views on left and right side of view pager

I have used viewpager which displays view with an image and radiobutton below. Each swipe screen is not a fragment, they are layouts which just swipe the same view with different imageview. The problem is that, I am unable to deselect the radio button which is in left and right side of the current view after i select the radio button of the current screen. If I return POSITION_NONE in getItemPosition(), it refresh the screen and radio button also deselected but the view is flickered. If i am able to call instantiateItem(), my problem is solved . But this method is called only when view is destroyed based on the setOffsetScreenPageLimit(). How can I achieved such requirements, if view pager cannot help?
Fragment:
public class AnswerImageDialogFragment extends DialogFragment implements ViewPager.OnPageChangeListener {
//member declaration
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
String strQuestion = null;
View rootView = inflater.inflate(R.layout.activity_viewpager_demo, container,
false);
getDialog().getWindow().requestFeature(Window.FEATURE_NO_TITLE);
intro_images = (ViewPager) rootView.findViewById(R.id.pager_introduction);
pager_indicator = (LinearLayout) rootView.findViewById(R.id.viewPagerCountDots);
//do some stuff
//set the adapter
mAdapter = new ViewPagerAdapter(getContext(), map);
intro_images.setAdapter(mAdapter);
intro_images.setCurrentItem(clickPosition);
intro_images.setOnPageChangeListener(this);
setUiPageViewController();
bus = EventBus.getDefault();
bus.register(this);
return rootView;
}
//other method
}
PagerAdapter:
public class ViewPagerAdapter extends PagerAdapter {
// member declaration
public ViewPagerAdapter(Context mContext, HashMap<String, Object> map) {
//other initialization
}
#Override
public int getCount() {
return optionImages.size();
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view == ((LinearLayout) object);
}
#Override
public Object instantiateItem(ViewGroup container, final int position) {
View itemView = LayoutInflater.from(mContext).inflate(R.layout.pager_item, container, false);
final ImageView ivOption = (ImageView) itemView.findViewById(R.id.answerId); // this is used as radio button in this case
/*The code snippet is to select the answer option based on whether answer is choosen or not.
If choosen, select as default in the pop up answer.
*/
if (null != ans) {
Iterator iterator = ans.iterator();
if (ans.size() > 0) {
int value = (int) iterator.next();
if (value == position) {
ivOption.setImageResource(R.drawable.ic_radio_button_tick);
} else {
ivOption.setImageResource(R.drawable.ic_radio_button_nontick);
}
}
}
p = position;
/*The code snippet is to change the answer value based on the user selection.
This means if user choosen another answer then clear the earlier choosen answer
*/
ivOption.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//do stuff
}
});
txtQuestion.setText(question);
txtOption.setText(optionsList.get(position));
imageView.setParseFile(optionImages.get(position));
imageView.loadInBackground();
container.addView(itemView);
return itemView;
}
#Override
public void destroyItem(ViewGroup container, int position, Object object) {
LinearLayout ll = (LinearLayout) object;
/*RelativeLayout ivOption = (RelativeLayout) ll.getChildAt(2);
ImageView iv = (ImageView) ivOption.getChildAt(1);
iv.setImageResource(R.drawable.ic_radio_button_tick);*/
container.removeView(ll);
}
#Override
public int getItemPosition(Object object) {
return super.getItemPosition(object);
}
public void refresh(ArrayList object) {
this.object = new ArrayList();
this.object.addAll(object);
this.notifyDataSetChanged();
}

Nested fragments: java.lang.IllegalArgumentException: No view found for id

I have a fragment A, containing a listview. To this listview I add a listheader containing a ViewPager that pages through childfragments.
When the user clicks an item in the list, the listfragment A gets replaced by a detail-view-fragment of that listitem.
I want the user to be able to go back to the list by clicking the back button.
So far everything works, except when the user presses the back button to pop the detail fragment from the stack to get back to the listview fragment A, the app crashes with an
java.lang.IllegalArgumentException: No view found for id 0x7f06002e (com.makamedia.hockeyweb:id/news_header_pager) for fragment NewsHeaderFragment{41f7b6f8 #0 id=0x7f06002e android:switcher:2131099694:0}
My suspicion is, that maybe the nested fragments for the viewpager in the listheader get recreated before the viewpager gets recreated, thus crashing the app, but I am not sure.
Any help is appreciated!
My ViewPagerAdapter for the listheader-viewpager (removed some unrelated code):
public class NewsHeaderAdapter extends FragmentPagerAdapter {
private int mCount;
public final NewsListAdapter mListAdapter;
public NewsHeaderAdapter(FragmentManager fm, int count, long autoSwipeInterval, NewsListAdapter adapter) {
super(fm);
this.mCount = count;
this.mListAdapter = adapter;
}
#Override
public Fragment getItem(int pos) {
return NewsHeaderFragment.getNew(this.mListAdapter.getItem(pos));
}
public void setCount(int newCount){
if(newCount < 1){
this.mCount = 1;
} else if(newCount >= this.mListAdapter.getCount()){
this.mCount = this.mListAdapter.getCount();
} else {
this.mCount = newCount;
}
}
#Override
public int getCount() {
return mCount;
}
#Override
public CharSequence getPageTitle(int position) {
return this.mListAdapter.getItem(position).getTitle();
}
}
My news detail fragment (pretty straight forward):
public class NewsHeaderFragment extends Fragment {
private NewsItem mNewsItem;
private TextView mHeaderNewsBigTitle;
private ImageView mHeaderNewsBigImage;
// Convenience method for creating a new fragment with parameters
public static NewsHeaderFragment getNew(NewsItem item){
NewsHeaderFragment fragment = new NewsHeaderFragment();
Bundle args = new Bundle();
args.putSerializable(Constants.SIG_NEWS_ITEM, item);
fragment.setArguments(args);
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.row_big_news, container, false);
Bundle newsHeaderArgs = getArguments();
mNewsItem = (NewsItem)newsHeaderArgs.getSerializable(Constants.SIG_NEWS_ITEM);
setupUI(rootView);
fillUI();
return rootView;
}
private void fillUI() {
mHeaderNewsBigTitle.setText(mNewsItem.getTitle());
Picasso.with(getActivity()).load(mNewsItem.getImageBig2x()).into(mHeaderNewsBigImage);
}
private void setupUI(View rootView) {
mHeaderNewsBigTitle = (TextView) rootView.findViewById(R.id.news_big_title);
mHeaderNewsBigImage = (ImageView) rootView.findViewById(R.id.news_big_img);
}
}
My viewpager is declared in xml in a row-layout and added like so:
private void addHeaderPager(int count) {
if(mNewsListAdapter != null && mNewsListAdapter.getCount()>0) {
if (count >= mNewsListAdapter.getCount()) {
count = mNewsListAdapter.getCount() - 1;
}
LayoutInflater inflater = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mHeader = (RelativeLayout) inflater.inflate(R.layout.row_big_news_pager, null);
mHeaderPager = (ViewPager) mHeader.findViewById(R.id.news_header_pager);
mHeaderPagerAdapter = new NewsHeaderAdapter(getChildFragmentManager(), count, 6000, mNewsListAdapter);
mHeaderPager.setOffscreenPageLimit(count);
mHeaderPager.setAdapter(mHeaderPagerAdapter);
// Bind the title indicator to the adapter
CirclePageIndicator circleIndicator = (CirclePageIndicator) mHeader.findViewById(R.id.news_header_pager_indicator);
circleIndicator.setViewPager(mHeaderPager);
mNewsListView.addHeaderView(mHeader);
}
}
Are you sure tha you use the right FragmentManager in addHeaderPager()?
I normally use getFragmentManager() and if there is a parent fragment I have to use getParentFragment().getFragmentManager() - if I don't I get the same error ("No view found for id") when trying to replace the current visible fragment.

Listview header laggy until scrolled

The header for my listview is pretty complex. It is a ViewPager / FragmentStatePagerAdapter with 5 fragments. The strange thing is that when the view first loads the whole listview is laggy. Once you scroll past the header the listview becomes smooth even when you scroll back up to the header. Any ideas on what may be happening? Thanks for any information
Fragment That contains ListView
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View featuredView = inflater.inflate(R.layout.fragment_featured_series, container, false);
ButterKnife.inject(this, featuredView);
View headerView = getHeaderView()
featuredList.addHeaderView(featuredListHeaderView);
sAdapter = new SeriesAdapter(getActivity(), new ArrayList<SeriesItem>());
featuredList.setAdapter(sAdapter);
return featuredView;
}
RelativeLayout getHeaderView() {
featuredListHeaderView = new FeaturedListHeaderView(getActivity(), this, rHeight, recentHeight);
featuredListHeaderView.setLayoutParams(params);
featuredListHeaderView.setVisibility(View.INVISIBLE);
return featuredListHeaderView;
}
}
The Header contains a Fragment which contains the pager
...
pagerAdapter = new FeaturedPagerAdapter(getActivity().getSupportFragmentManager(), new ArrayList<SeriesItem>());
viewPager.setAdapter(pagerAdapter);
pageIndicator.setViewPager(viewPager);
private class FeaturedPagerAdapter extends FragmentStatePagerAdapter {
private List<SeriesItem> seriesItems = new ArrayList<SeriesItem>();
public FeaturedPagerAdapter(FragmentManager fm, List<SeriesItem> sItems) {
super(fm);
this.seriesItems = sItems;
}
#Override
public Fragment getItem(int i) {
FeaturedPageFragment pf = new FeaturedPageFragment(seriesItems.get(i));
return pf;
}
#Override
public int getCount() {
return seriesItems.size();
}
#Override
public CharSequence getPageTitle(int position) {
return seriesItems.get(position).getName();
}
public void setItems(List<SeriesItem> items) {
this.seriesItems = items;
notifyDataSetChanged();
pageIndicator.notifyDataSetChanged();
}
}
FeaturedPageFragment just contains a image with some click listeners

Setting Data in ViewPagerIndicatorin different layouts

I have 3 different layouts on my ViewPagerIndicator - https://github.com/JakeWharton/Android-ViewPagerIndicator
My project is to load data from the website and set the data accordingly into the 3 different layout of the ViewPager.
How do I go about achieving it?
In my TestFragment, I have
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Log.i("mContent", mContent);
View view = null;
if (mContent.equalsIgnoreCase("title1")) {
view = inflater.inflate(R.layout.one, container, false);
} else if (mContent.equalsIgnoreCase("title2")) {
view = inflater.inflate(R.layout.two, container, false);
} else if (mContent.equalsIgnoreCase("title3")) {
view = inflater.inflate(R.layout.three, container, false);
//Textview data = (TextView)view.findViewById(id)
}
return view;
}
I know this is for setting layout according to the fling'd titles.
I know how to findViewById to get the id of the widgets and set data. However, the data is set statically in the code itself.
For me, I have to grab data from the internet and put the data in accordingly. How do I achieved that?
Thanks in advance.
I almost know what you want.Here is my answers,and it works well.
You can according to the following steps.
1.Create three different Fragment class ,such as LoadImageFragment1,LoadImageFragment2,LoadImageFragment3, and all of them extends Fragment.
Follow is my example.
public class LoadImageFragment1 extends Fragment {
ListView listView;
LayoutInflater mInflater;
LoadImageAdapter adapter;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
mInflater = inflater;
View view = inflater.inflate(R.layout.loadimage_layout, null);
listView = (ListView) view.findViewById(R.id.listview);
adapter = new LoadImageAdapter();
adapter.initList();
listView.setAdapter(adapter);
return view;
}
private class LoadImageAdapter extends BaseAdapter{
ArrayList<String> list = new ArrayList<String>();
public void initList(){
for(int i = 0 ; i < 30;i ++){
list.add("" + i);
}
}
#Override
public int getCount() {
return list.size();
}
#Override
public Object getItem(int position) {
return position;
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null){
convertView = mInflater.inflate(R.layout.loadimage_item, null);
}
return convertView;
}
}
2.Then modify your SampleTabsDefault class.
class GoogleMusicAdapter extends FragmentPagerAdapter {
public GoogleMusicAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
// return TestFragment.newInstance(CONTENT[position % CONTENT.length]);
switch(position){
case 0:
return new LoadImageFragment1();
case 1:
return new LoadImageFragment2();
case 2:
return new LoadImageFragment3();
}
}
#Override
public CharSequence getPageTitle(int position) {
return CONTENT[position % CONTENT.length].toUpperCase();
}
#Override
public int getCount() {
return CONTENT.length;
}
}
And I just use the class of SampleTabsDefault as a sample.You can do this in other classes.
Here I just use a ListView as a sample , you can load your images and texts from internt, and you also can do other things in your LoadImageAdapter 's getView() method.
Hope this can help you.
I have 3 different layouts on my ViewPagerIndicator
ViewPagerIndicator is just an indicator
I thought your meaning is your viewadapter have three views to show.
Use FragmentPagerAdapter to handle different view.
you should read the ViewPagerIndicator samples
Before starting, copy the samples from ViewPagerIndicator
https://github.com/JakeWharton/Android-ViewPagerIndicator/tree/master/sample/src/com/viewpagerindicator/sample
The steps to be done are,
Create an custom FragmentPagerAdapter (ex: https://github.com/JakeWharton/Android-ViewPagerIndicator/blob/master/sample/src/com/viewpagerindicator/sample/TestFragmentAdapter.java)
Create custom Fragment for each each layout (in your case 3)
https://github.com/JakeWharton/Android-ViewPagerIndicator/blob/master/sample/src/com/viewpagerindicator/sample/TestFragment.java
Override onActivityCreated in the fragment class
In the onActivityCreated method, u can access the UI components as in onCreate method
So that u can make a web service call, bind it to ur UI components in this segment.
Cheers
Create and implement a Loader (AsyncTaskLoader) to load data from the internet.
Have your TestFragment implement LoaderCallbacks, so that it gets notified when the Loader (AsyncTaskLoader) has finished loading data from the internet.
In your implementation of your TestFragment's onActivityCreated, initialize or restart the loader:
getLoaderManager().initLoader(0, null, this);
In your TestFragment's implementation of onLoadFinished, assign the data to the widgets.
https://developer.android.com/reference/android/content/AsyncTaskLoader.html
https://developer.android.com/reference/android/app/LoaderManager.html
https://developer.android.com/reference/android/app/LoaderManager.LoaderCallbacks.html

Switching fragments

I need to change Fragment in View pager
I have getItem method in View pager adapter
#Override
public Fragment getItem(int position) {
fragmentPosition = position;
Log.e("PageAdapter", "Creating fragment at: " + position);
DefinedValues.thumbnailInfo.put("activity", DefinedValues.images);
DefinedValues.thumbnailInfo.put("type", "info");
DefinedValues.thumbnailInfo.put("page", position+ 1 + "");
String request = Json.stringToJson(DefinedValues.thumbnailInfo);
DefinedValues.thumbnailInfo.clear();
StringAsyncRetriever net = new StringAsyncRetriever();
net.setListener(MyPagerAdapter.this);
net.execute(request, DefinedValues.GET_DATA);
Log.d(TAG, "got item # " + position);
fragment1 myFragment = new fragment1();
return myFragment;
}
And I need to change it when the AsyncTask has finished to the one that shows images
There is the fragment1 class:
public class fragment1 extends Fragment {
GridView gridView;
public ImageAdapter adapter;
public int position;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
//
Bundle savedInstanceState) {
adapter = new ImageAdapter(this.getActivity(), position);
if (container == null) {
Log.e("Null container", "Null");
return null;
}
//Log.e("fragment1", "fragment1 reached!");
View view = inflater.inflate(R.layout.menu1_fragment, container, false);
gridView = (GridView)view.findViewById(R.id.gridview1);
gridView.setAdapter(adapter);
DefinedValues.adapterContainer.add(adapter);
//Log.d("Fragment1 adapter count: ", DefinedValues.adapterContainer.size() + "");
/* gridView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
ImageView imageView = new ImageView(getActivity());
LinearLayout.LayoutParams vp = new LinearLayout.LayoutParams
(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
imageView.setLayoutParams(vp);
imageView.setImageBitmap(DefinedValues.imageContainer.get(position).getThumbnail());
getActivity().addContentView(imageView, vp);
}
});
*/
return gridView;
}
So how can I add gridView to fragment only when asyncTask ends?
You should let the ViewPager handle the changing of fragments. You can return the correct fragment in the getItem. Just hide everything in that fragment and optionally render other stuff that you are doing in FragmentDummy. And then, pass in the fragment to your AsyncTask or get the fragment by id/tag in your AsyncTask. You can then show the correct content view in the fragment after the task finishes and hide the dummy part of the fragment.

Categories

Resources