Android: How to use PDFViewer with Fragments - android

I have a requirement where I need to display PDF file within my Android app. I have used PDFViewer.jar to do so in some of my Activities, which is explained here https://github.com/jblough/Android-Pdf-Viewer-Library . Now I am stuck up with displaying PDF file inside a Fragment. But PDFViewer.jar has been limited to Activity. I have seen the source code of PDFViewer.jar and am unable to convert it for Fragment. Can anyone help me please.
Thanks

You should take, PdfViewerActivity.java (https://github.com/jblough/Android-Pdf-Viewer-Library/blob/master/src/net/sf/andpdf/pdfviewer/PdfViewerActivity.java), rename it to PdfViewerFragment.java.
Change extends Activity to extends Fragment in Android Studio, and correct each red line.
Also, don't forget to import the rest of the project (or you'll have missing classes)
You should especially change each need of Context (this) by getActivity() and findViewById() by getView().findViewById(R.id.foo).
Surely, it won't be enough, but it's a good place to start.

This is load PDF in fragment use PDFViewer
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_keluarga, container, false);
pdfView = (PDFView) v.findViewById(R.id.keluargaPdf);
pdfView.fromAsset("tiga.pdf").load();
// Inflate the layout for this fragment
return v;
}

Related

How onCreateView works

I started a TabLayout Activity, which includes the following code to create the fragment:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_find, container, false);
TextView textView = (TextView) rootView.findViewById(R.id.section_label);
textView.setText(getString(R.string.section_format, getArguments().getInt(ARG_SECTION_NUMBER)));
return rootView;
}
I've read the official documentation and still unsure how it works. If somebody could explain in detail how each part here is working that would be great.
Edit: Mainly referring to View rootView = inflater.inflate(R.layout.fragment_find, container, false); what each of these 3 parameters are doing and how inflater.inflate() is working here.
OK, here we go.
The process of inflating is simply creating your view explicitly instead of doing this implicitly, this is by using this:
public void onCreate(){
setContentView(R.layout.your_layout);
}
Compare with this question.
Now with the arguments. Compare this with this section.
R.layout.fragment_find returns ID of a fragment used somewhere in the code. R is a dynamic android class used for manipulating some of your app's resources such as views, strings etc. Compare.
container is a root from some ViewGroup. So you hgave a group of, say, buttons doing common things (for example choosing some colour in your application), and they all have same parent, in your case called a container.
attachToRoot is the last argument. According to docs:
If false, root is only used to create the correct subclass of LayoutParams for the root view in the XML.
So it is not attached to the parent we talked about in last point. Compare here.
I hope this helped.
onCreateView():
After the onCreate() is called (in the Fragment), the Fragment's onCreateView() is called. You can assign your View variables and do any graphical initialisations. You are expected to return a View from this method, and this is the main UI view, but if your Fragment does not use any layouts or graphics, you can return null (happens by default if you don't override).
Here, it's a method of the lifecycle for Fragment.

Random ClassCastExceptions to apparently random views using findViewById

I don’t consider myself an experienced developer, but I can say that I’m experienced enough to avoid ClassCastExceptions on views: I know which view is linked to which id in my layout.
What’s happening is that I’m getting silly crashes along the line of:
TextView v = (TextView) view.findViewById(R.id.my_text_view);
ClassCastException: cannot cast AppCompatImageView to TextView
in different parts of the app, but not in a reproducible way (it doesn’t happen every time I do that particular action). This is driving me crazy!
Examples
// IN A AppCompatDialogFragment
// R.layout.sheet_menu is a frame with only two childs:
// a TextView and a RecyclerView.
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.sheet_menu, container, false);
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
titleView = (TextView) view.findViewById(R.id.menu_sheet_title);
list = (RecyclerView) view.findViewById(R.id.menu_sheet_list);
// CLASSCASTEXCEPTION! Cannot cast AppCompatTextView to RecyclerView!
}
And another:
// IN A RECYCLERVIEW ADAPTER
// Inflating the view holder layout with
// View.inflate(mContext, R.layout.editable_story, null);
private class EditableStoryHolder extends PrimaryHolder {
public EditableStoryHolder(View itemView) {
super(itemView);
...
likes = (TextView) itemView.findViewById(R.id.likes_count);
// CLASSCASTEXCEPTION! Cannot cast AppCompatImageView to TextView
}
Double Checked
I’m never explicitly calling removeView or anything else
I am importing the right package R class
The ids I’m using are unique in all the project, and I’m pretty sure they are not used inside any of my dependencies
So, what’s happening? Why does findViewById return the wrong child? I’m testing on API23, using support libraries v. 23.2.1. This is a pretty new issue. Something wrong with the appcompat layout inflater?
Sometimes the generated R file becomes out of sync (not sure why but I experience this issue often)
Simply clean the project by selecting Build -> Clean Project
This should regenerate the R files and solve the issue, you may have to clean the project everytime you add a new view to a layout
Did you introduce library that will affect the LayoutInflater or related factories? Make sure the inflater create a correct view. I think you can debug into LayoutInflater.java to make sure everything works correctly.

The method findViewById(int) is undefined for the type

I get the error
The method findViewById(int) is undefined for the type PM_section
when trying to implement my Expandable ListView. I am sure this is a common error, but I am having trouble finding a solution. I am attempting to learn fragments and such, and it has been an uphill battle ever since I started. I have done a fair bit of searching, and found a lot of results, that don't seem to help me in my case.
If someone could give me any insight, or point me in the right direction I would greatly appreciate it.
My small test class is below
public class PM_section extends Fragment {
// CustomExpListView custExpListView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
View V = inflater.inflate(R.layout.fragment_pm_section_test, container, false);
CustomExpListView custExpListView = (CustomExpListView)
this.findViewById(R.id.ExpandableListView01);
return V;
}// end on create
}
The CustomExpListView class was pretty much copy, pasted from the Android Sample Projects, and is happy and has no problems.
Thanks you for helping me out.
If R.id.ExpandableListView01 is part of R.layout.fragment_pm_section_test, then replace this with V.
CustomExpListView custExpListView = (CustomExpListView)
V.findViewById(R.id.ExpandableListView01);
Fragments do not have a findViewById() method. You need to use your inflated View instead to get everything from your layout.
Also consider using Java naming conventions. Variables start with lowercase letters while Classes start with Uppercase letters.
Simply get the fragment's root view by calling getView() and then call findViewById() method:
getView().findViewById(R.id.ExpandableListView01);
Without it you will not be able to use findViewById() as Fragment class doesn't itself have such method.

Demo Master Detail View - Detail Fragment Change Content

Context: I'm using the Wizard with in Eclipse and ADT to get a master detail view framework.
I have a good understanding of the fragments need to sit with in an activity and that with in a view etc how ever looking at the example I'm trying to work out how best to change it so I can start developing a app my self.
Is the 'dummy' content view actually needed ? All it seems to contain is the menu options ?
The questions I have is does any one know how the detail view is created ? From what I am reading the app is just taking the item ID and placing it in the detail view as text ?
Extract from Itemdetailfragment:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_item_detail, container, false);
if (mItem != null) {
((TextView) rootView.findViewById(R.id.item_detail)).setText(mItem.content);
}
return rootView;
}
Is the best way to re do a detail fragment for each new screen I need and place some logic behind that or code the existing one to look at the menu option selected and display the right code ?
Finally is this the best example to start working with ?
The questions I have is does any one know how the detail view is
created ? From what I am reading the app is just taking the item ID
and placing it in the detail view as text ?
Yes, that is exactly what it is doing. This is done in the detail fragment
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_team_detail,
container, false);
// Show the dummy content as text in a TextView.
if (mItem != null) {
((TextView) rootView.findViewById(R.id.team_detail))
.setText(mItem.content);
}
return rootView;
}
You need to change it to get whatever data you need from whatever source you want to use (website, database or change the hard coded values
If you look at the DummyContent.java class you will see the comment
/** TODO: Replace all
uses of this class before publishing your app. */
Basically you should re-write this class to get the data that you want
I've actually added action bar sherlock to make this compatible with api 8 with a little help from this question Two questions about Master/Detail Flow Template
There is a hint that you could use ContentLoader in conjunction with a ContentProvider to get your data from another source such as a database or a web service

Layout in Dynamic Fragments

I'm writing a calculator application in which I would like to be able to switch between 4 modes of calculation: Decimal, Binary, Octal, and Hex. In order to manage the different UIs for the different modes, I have 4 Fragment subclasses in my Activity. Each Fragment has its own XML layout file, in addition to the main XML file for the Activity. I found a guide on the Android Developer site for inflating layouts for Fragments, and I've followed that guide. However, I would like to add listeners and so on to the various components of the layouts, preferably within the onCreateLayout method of the Fragment, or somewhere else where I could do it easily and minimize code duplication.
It appears, however, that when I try to call findViewByID to access one of the inflated Views (after I've called LayoutInflater.inflate, obviously), I get a null return value. This issue occurs whether I call findViewByID from within onCreateLayout or from elsewhere in the Activity (after the Views have, theoretically, been created). What's going wrong here?
One issue I think might be a problem is that I've overloaded the names of the Views between the various Fragment layouts. For example, the "1" button in the Binary layout has the same ID as the "1" button in the Hex layout. Is this allowed, assuming the Binary and Hex layouts are never both part of the Activity at the same time?
Thanks.
I think same id in different layout is not problem in Fragement. First you have to catch the inflated view then find whatever inside this. For example --
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view = inflater.inflate(R.layout.frg1, container, false);
android.util.Log.v("", "!!!!!!!!!! Frg1 !!!!!!!!!");
Button b = (Button) view.findViewById(R.id.b1);
b.setOnClickListener(new View.OnClickListener(){
public void onClick(View v) {
Toast.makeText(getActivity(), "here", Toast.LENGTH_SHORT).show();
}
});
return view;
}

Categories

Resources