My application pulls data from a web service that generates different sections for each user. Then I am going to use these sections to create tabs using FragmentPagerAdapter.
I have used an Async task to pull data from the web service. However the overridden methods such as getCount() and getPageTitle() in the FragmentPagerAdapter executed prior to my asynctask and completes its job. How can I prevent this and generate dynamic number of tabs and their title name based on the data fetched from the web service?
In other words how can I create dynamic number of tabs and titles based on the data fetch from the web service
My Code for FragmentPagerAdapter as below. As you can see I have hard coded the amount of tabs as well as their title names.
public class SectionsPagerAdapter extends FragmentPagerAdapter{
private boolean proceedStatus = false;
private String requestURL = "xxxxxxxxxxxxxxxxxxxxxxxx";
//list of fragments need to be added dynamically
public final ArrayList<Fragment> screens = new ArrayList<Fragment>();
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
// getItem is called to instantiate the fragment for the given page.
// Return a DummySectionFragment (defined as a static inner class
// below) with the page number as its lone argument.
Fragment fragment = new SectionFragment();
Bundle args = new Bundle();
args.putInt(SectionFragment.ARG_SECTION_NUMBER, position + 1);
fragment.setArguments(args);
return fragment;
}
#Override
public int getCount() {
return 2;
}
#Override
public CharSequence getPageTitle(int position) {
Locale l = Locale.getDefault();
switch (position) {
case 0:
return "Camera".toUpperCase(l);
case 1:
return getString(R.string.title_section2).toUpperCase(l);
case 2:
return getString(R.string.title_section3).toUpperCase(l);
case 3:
return "SECTION 4";
}
return null;
}
//setting the section title
private void setSectionTitle(){
}
//count the number of sections
private int countNumberofSections(){
int numberOfSection = 0;
return numberOfSection;
}
}
Then I have my Fragment code as below which has the the caller to the Async Task
public static class SectionFragment extends Fragment implements OnTaskCompleted {
/**
* The fragment argument representing the section number for this
* fragment.
*/
private Slider adapter;
private ViewPager viewPager;
public static final String ARG_SECTION_NUMBER = "section_number";
Button thumbUpBut;
Button thumbDownBut;
Button captureButton;
ImageView genImage;
TextView genCaption;
private Camera mCamera;
private CameraPreview mPreview;
private static File mediaFile;
private ProgressDialog progress;
private static String imageSaveLocation;
private static String file_name_without_extension;
private ImageView imageView;
private Button uploadButton;
private Button cancelButton;
private Collection<Place> places = null;
private Collection<Happenings> events = null;
private Collection<General> general = null;
private ArrayList<String> sections;
public int getNumberOfPages(){
return sections.size();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main_dummy,container, false);
TextView dummyTextView = (TextView) rootView.findViewById(R.id.section_label);
dummyTextView.setText(Integer.toString(getArguments().getInt(ARG_SECTION_NUMBER)));
FeedRequest task = new FeedRequest(this);
task.execute("xxxxxxxxxxxxxxxxxxxxxxxxxxxxx");
captureButton = (Button) rootView.findViewById(R.id.button_capture);
captureButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
takePhoto();
}
});
thumbUpBut = (Button) rootView.findViewById(R.id.thumbUp);
thumbUpBut.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Log.v("thumbPress", "thumbPressUp");
thumb("up");
}
});
thumbDownBut = (Button) rootView.findViewById(R.id.thumbDown);
thumbDownBut.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Log.v("thumbPress", "thumbPressDown");
thumb("down");
}
});
//allocating the activity one to the camera
if(getArguments().getInt(ARG_SECTION_NUMBER) == 1){
mCamera = getCameraInstance();
mPreview = new CameraPreview(this.getActivity(), mCamera);
FrameLayout preview = (FrameLayout)rootView.findViewById(R.id.camera_preview);
preview.addView(mPreview);
//hide buttons
thumbDownBut.setVisibility(rootView.INVISIBLE);
thumbUpBut.setVisibility(rootView.INVISIBLE);
}else{
thumbDownBut.setVisibility(rootView.VISIBLE);
thumbUpBut.setVisibility(rootView.VISIBLE);
captureButton.setVisibility(rootView.INVISIBLE);
}
viewPager = (ViewPager) rootView.findViewById(R.id.pager);
return rootView;
}
//take photo function
private void takePhoto() {
//get coordinates of the location
UserLocation userLocation = new UserLocation();
userLocation.getUserLocation(getActivity());
coordinates[0] = userLocation.longitude;
coordinates[1] = userLocation.latitude;
PictureCallback pictureCB = new PictureCallback() {
public void onPictureTaken(byte[] data, Camera cam) {
new SavePhotoAndMetadata().execute(data);
cam.startPreview();
}
};
mCamera.takePicture(null, null, pictureCB);
}
//get camera instance
private Camera getCameraInstance() {
Camera camera = null;
try {
camera = Camera.open();
} catch (Exception e) {
// cannot get camera or does not exist
}
return camera;
}
//get the media out
private static File getOutputMediaFile() {
File mediaStorageDir = new File(Environment.getExternalStorageDirectory() + "/Android/data/asia.ceynet.realsnap/temp_img");
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
Log.d("MyCameraApp", "failed to create directory");
return null;
}
}
// Create a media file name
String timeStamp = (DateFormat.format("dd-MM-yyyy hh:mm:ss", new java.util.Date()).toString());
mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_" + timeStamp + ".jpg");
file_name_without_extension = "IMG_" + timeStamp;
imageSaveLocation = mediaFile.toString();
return mediaFile;
}
//saving the image and metadata together
class SavePhotoAndMetadata extends AsyncTask<byte[], String, String> {
#Override
protected String doInBackground(byte[]... data) {
File picFile = getOutputMediaFile();
if (picFile == null) {
return null;
}
byte[] photoData = data[0];
try {
//save the image
FileOutputStream fos = new FileOutputStream(picFile);
fos.write(photoData);
fos.close();
} catch (FileNotFoundException e) {
e.getStackTrace();
} catch (IOException e) {
e.getStackTrace();
}
return null;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
progress = new ProgressDialog(getActivity());
progress.setMessage("Saving Picture..Please wait...");
progress.show();
}
#Override
protected void onPostExecute(String s) {
progress.dismiss();
imagePreviewDialog();
}
}
//save image metadata in async task
class SaveMetadataTask extends AsyncTask<Void, String, Void> {
#Override
protected Void doInBackground(Void... params) {
serializeDeserialize.serializeData("This is for testing", file_name_without_extension, Double.toString(coordinates[0]), Double.toString(coordinates[1]), deviceId, deviceEmail);
return null;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected void onPostExecute(Void v) {
}
}
//image preview dialog and its functionality
private void imagePreviewDialog(){
//setting the bitmap
Bitmap bmp = BitmapFactory.decodeFile(mediaFile.toString());
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("Image Preview");
builder.setCancelable(false);
LayoutInflater inflater = getActivity().getLayoutInflater();
ViewGroup vg = (ViewGroup)inflater.inflate(R.layout.sanp_preview_layout, null);
ImageView image = (ImageView) vg.findViewById(R.id.imageView);
image.setImageBitmap(rotateBitmap(bmp));
builder.setView(vg);
//buttons
builder.setPositiveButton("Upload",new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
if(checkInternetConnection.haveNetworkConnection(sContext)){
//upload the image
uploadImage();
//save image metadata
new SaveMetadataTask().execute();
}else{
Toast.makeText(sContext, "Error! No internet connection detected. Image will be uploaded on an active internet connection", Toast.LENGTH_LONG).show();
new SaveMetadataTask().execute();
}
}
});
builder.setNegativeButton("Discard",new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
discardImage(mediaFile.toString());
dialog.dismiss();
}
});
builder.show();
}
private Bitmap rotateBitmap(Bitmap image){
int width=image.getHeight();
int height=image.getWidth();
Bitmap srcBitmap=Bitmap.createBitmap(width, height, image.getConfig());
for (int y=width-1;y>=0;y--)
for(int x=0;x<height;x++)
srcBitmap.setPixel(width-y-1, x,image.getPixel(x, y));
return srcBitmap;
}
//device email
private String getDeviceEmail(){
AccountManager accountManager = AccountManager.get(sContext);
Account[] account = accountManager.getAccountsByType("com.google");
//device email
for(Account accLoop : account){
deviceEmail = accLoop.name;
}
return deviceEmail;
}
//upload image to the server
private void uploadImage(){
//save metadata
//call upload service
Intent intent = new Intent(sContext, HttpUploader.class);
Bundle loc = new Bundle();
loc.putDoubleArray("ss", coordinates);
intent.putExtra("url", PHOTO_UPLOAD);
intent.putExtra("paths", mediaFile.toString());
intent.putExtra("deviceid", deviceId);
intent.putExtra("deviceemail", getDeviceEmail());
intent.putExtra("posttext", "This is for testing");
intent.putExtra("filename", file_name_without_extension);
intent.putExtra("geo", loc);
sContext.startService(intent);
Toast.makeText(getActivity(), "Your image is being uploaded", Toast.LENGTH_LONG).show();
}
//discard image when the discard button is pressed
private void discardImage(String imagePath){
File file = new File(imagePath);
try{
file.delete();
}catch(Exception e){
Log.e("IMAGE_DELETION_ERROR", e.toString());
}
}
#Override
public void onTaskCompleted(boolean status, String message) {
// TODO Auto-generated method stub
Log.e("onTaskCompleted", "success" + status);
if (message == "tumb UP success") {
thumbUpBut.setSelected(true);
thumbDownBut.setSelected(false);
Log.e("tumb", "tumb");
} else if (message == "tumb DOWN success") {
thumbDownBut.setSelected(true);
thumbUpBut.setSelected(false);
Log.e("tumb", "tumb");
}
}
//listener for fetching main objects
#Override
public void onFeedCompleted(ArrayList<Posts> postArray, Multimap<String, Object> multiMap) {
// TODO Auto-generated method stub
numberOfPages = postArray.size();
adapter = new Slider(getActivity(), postArray, getContext());
viewPager.setAdapter(adapter);
// displaying selected image first
viewPager.setCurrentItem(postArray.size());
//saving the keyset
Set<String> keys = multiMap.keySet();
sections = new ArrayList<String>();
//sorting the categories and creating the category list
for(String key:keys){
//getting category list
if(!sections.contains(keys)){
sections.add(key);
}
//sorting categories
if(key.equals("Place")){
places.add((Place) multiMap.get(key));
}else if(key.equals("Events")){
events.add((Happenings) multiMap.get(key));
}else if(key.equals("General")){
general.add((General) multiMap.get(key));
}
}
}
//adding the pages to the adaptor dynamically
public void addPagesDynamically(){
}
}
//create the parent directory
private void createParentDiectory(){
File dir = new File(Environment.getExternalStorageDirectory() + "/Android/data/asia.ceynet.realsnap");
if(!(dir.exists() && dir.isDirectory())) {
dir.mkdirs();
}
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle presses on the action bar items
switch (item.getItemId()) {
case R.id.action_post:
openPost();
return true;
case R.id.action_settings:
// openSettings();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
public void openPost() {
/*
Intent i = new Intent(getApplicationContext(), PhotoActivity.class);
startActivity(i);
*/
}
public static void thumb(String type) {
SectionFragment d = new SectionFragment();
PostThumb task = new PostThumb(type, d);
task.execute("xxxxxxxxxxxxxxxxxxxxxxxxxxxx");
}
//broadcast receiver for picture upload
public class MyWebRequestReceiver extends BroadcastReceiver {
public static final String PROCESS_RESPONSE = "asia.ceynet.intent.action.PROCESS_RESPONSE";
#Override
public void onReceive(Context context, Intent intent) {
//String responseString = intent.getStringExtra(HttpUploader.RESPONSE_STRING);
String reponseMessage = intent.getStringExtra(HttpUploader.RESPONSE_MESSAGE);
String responseStatus = intent.getStringExtra(HttpUploader.RESPONSE_STATUS);
String file_to_be_deleted = intent.getStringExtra(HttpUploader.FILE_NAME_WITHOUT_EXTENSION);
Toast.makeText(getApplicationContext(), reponseMessage + " - " + file_to_be_deleted + ".jpg", Toast.LENGTH_LONG).show();
//if uploaded successfully delete or image and metadata
if(responseStatus.equals("true")){
File temp_image_dir = new File(Environment.getExternalStorageDirectory() + "/Android/data/asia.ceynet.realsnap/temp_img/" + file_to_be_deleted + ".jpg");
File metadata_file = new File(Environment.getExternalStorageDirectory() + "/Android/data/asia.ceynet.realsnap/temp_img/" + file_to_be_deleted + ".ser");
try{
temp_image_dir.delete();
metadata_file.delete();
}catch(Exception e){
Log.e("IMAGE_DELETION_ERROR", e.toString());
}
}
}
}
When you finnish pulling the async data, provide the adapter with the new data and call .notifyDataSetChanged() on that adapter instance and the framework will update the pages and count by itself.
If you wish a more detailed explanation post your FragmentPagerAdapter implementation.
First of all, let me apologize if I'm not making myself clear enough because this is one of my first participation(s) here. But I'll be always here to answer queries related to this answer and clear any confusions arose by my statements.
Since you're using fragments, so I'm assuming you must have included your fragments inside an activity (lets say MainActivity.java).
What you need, can be done inside that activity containing fragment.
Here is the example code of onCreate method inside the MainActivity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FragmentManager fragmentManager = getSupportFragmentManager();
//Instance of viewpager included inside activity_main.xml
viewPager = (ViewPager) findViewById(R.id.vpMain);
SectionsPagerAdapter adapter = new SectionsPagerAdapter (fragmentManager);
//Adding some fragments right from the beginning, you could ignore it if not needed.
addFragments();
//This `OnPageChangeListener` will do the trick for you.
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
//Show the title of fragment
Toast.makeText(MainActivity.this, adapter.screens.get(position), Toast.LENGTH_SHORT).show();
//If fragment being loaded is later than the first one,
// then add one more fragment after the last fragment to the adapter.
// integer currentPosition is declared as a field, outside onCreate method and initially set to 0.
if(position>currentPosition){
currentPosition+=1;
adapter.addFragment(new SectionFragment(), "Fragment"+String.valueOf(position+3));
adapter.notifyDataSetChanged();
}else{
currentPosition--;
}
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
} // onCreate ends here.
Create this method inside your MainActivity (just to add 3 fragments to give your application a head-start.
private void addFragments(){
adapter.addFragment(new SectionFragment());
adapter.addFragment(new SectionFragment());
adapter.addFragment(new SectionFragment());
}
Then modify your SectionsPagerAdapter's getItem and getCount methods as below:
public class SectionsPagerAdapter extends FragmentPagerAdapter{
private boolean proceedStatus = false;
private String requestURL = "xxxxxxxxxxxxxxxxxxxxxxxx";
//list of fragments need to be added dynamically
public final ArrayList<Fragment> screens = new ArrayList<Fragment>();
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
return screens.get(position);
}
#Override
public int getCount() {
return screens.size();
}
//This method will dynamically add a fragment each time it is called.
public void addFragment(Fragment fragment) {
screens.add(fragment);
}
Now, no work related to "adding new fragment to the list" needs to be done inside your SectionFragment class.
Related
I have an activity called FiltersAndEditActivity and two fragments inside it. Inside one of the fragments I am running the following code:
public void prepareThumbnail(final Bitmap bitmap) {
Runnable r = new Runnable() {
public void run() {
Bitmap thumbImage;
if (bitmap == null) {
thumbImage = BitmapUtils.getBitmapFromAssets(getActivity(), FiltersAndEditActivity.IMAGE_NAME, 100, 100);
} else {
thumbImage = Bitmap.createScaledBitmap(bitmap, 100, 100, false);
}
if (thumbImage == null)
return;
ThumbnailsManager.clearThumbs();
// add normal bitmap first
ThumbnailItem thumbnailItem = new ThumbnailItem();
thumbnailItem.image = thumbImage;
thumbnailItem.filterName = "normal";
ThumbnailsManager.addThumb(thumbnailItem);
List<Filter> filters = FilterPack.getFilterPack(activity);
for (Filter filter : filters) {
ThumbnailItem tI = new ThumbnailItem();
tI.image = thumbImage;
tI.filter = filter;
tI.filterName = filter.getName();
ThumbnailsManager.addThumb(tI);
}
thumbnailItemList.addAll(ThumbnailsManager.processThumbs(context));
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
mAdapter.notifyDataSetChanged();
}
});
}
};
new Thread(r).start();
}
processThumbs method code (inside a Util class named ThumbnailManager):
public static List<ThumbnailItem> processThumbs(Context context) {
for (ThumbnailItem thumb : filterThumbs) {
// scaling down the image
float size = context.getResources().getDimension(R.dimen.thumbnail_size);
thumb.image = Bitmap.createScaledBitmap(thumb.image, (int) size, (int) size, false);
thumb.image = thumb.filter.processFilter(thumb.image);
// cropping circle
// TODO - think about circular thumbnails
// thumb.image = GeneralUtils.generateCircularBitmap(thumb.image);
processedThumbs.add(thumb);
}
return processedThumbs;
}
FiltersAndEditActivity code where I am calling prepareThumbmail method of fragment:
private void setupViewPager(ViewPager viewPager) {
ViewPagerAdapterr adapter = new ViewPagerAdapterr(getSupportFragmentManager());
// adding filter list fragment
filtersListFragment = new FiltersListFragment();
filtersListFragment.setListener(this);
// adding edit image fragment
editImageFragment = new EditImageFragment();
editImageFragment.setListener(this);
adapter.addFragment(filtersListFragment, getString(R.string.tab_filters));
adapter.addFragment(editImageFragment, getString(R.string.tab_edit));
viewPager.setAdapter(adapter);
}
static class ViewPagerAdapterr extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapterr(FragmentManager manager) {
super(manager);
}
#Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
#Override
public int getCount() {
return mFragmentList.size();
}
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
}
private void setImage(){
intent = getIntent();
FiltersListFragment filtersListFragment = new FiltersListFragment();
if(intent.hasExtra(getString(R.string.selected_image))){
imgUrl = intent.getStringExtra(getString(R.string.selected_image));
Log.d(TAG, "setImage: got new image url: " + imgUrl);
originalImage = ImageManager.getBitmap(imgUrl);
filteredImage = originalImage.copy(Bitmap.Config.ARGB_8888, true);
finalImage = originalImage.copy(Bitmap.Config.ARGB_8888, true);
imagePreview.setImageBitmap(originalImage);
filtersListFragment.prepareThumbnail(originalImage);
}
}
But getActivity(), getContext(), activity.this, simply this : all are returning null on this line: ThumbnailManager.processThumbs(getContext). Earlier, activity.runOnUiThread() was also returning null but no idea how it got fixed. I have tried some solutions on similar questions but none of them have worked so far. Any lead would be appreciated.
As i mentioned earlier, this error is occurring due to Fragment is not attached to any activity.
private void setImage(){
intent = getIntent();
FiltersListFragment filtersListFragment = new FiltersListFragment();
// it will add filterListFragment into container and container is defined in your current activity xml file where you want to show this fragment
getSupportedFragmentManager().beginTransaction()
.replace(R.id.container, filtersListFragment)
.commit();
if(intent.hasExtra(getString(R.string.selected_image))){
imgUrl = intent.getStringExtra(getString(R.string.selected_image));
Log.d(TAG, "setImage: got new image url: " + imgUrl);
originalImage = ImageManager.getBitmap(imgUrl);
filteredImage = originalImage.copy(Bitmap.Config.ARGB_8888, true);
finalImage = originalImage.copy(Bitmap.Config.ARGB_8888, true);
imagePreview.setImageBitmap(originalImage);
filtersListFragment.prepareThumbnail(originalImage);
}
}
Some references:
How to use fragment
Adding fragment programmatically
Edit
as viewpager is being used and its different issue then previous so i'm adding other answer here
in your activity you're shadowing fragment object which leads to this error as the new fragment is not attached to activity still you're trying to call it's method. so make following changes to make it working.
private void setImage(){
intent = getIntent();
// we have to remove below line as it create new object of FiltersListFragment instead we use the same object as defined in setupViewPager() method
//FiltersListFragment filtersListFragment = new FiltersListFragment();
....
}
My Main Activity has three tabs. Each tab is a fragment. Now if you change the theme (white and dark are available), the activity is being recreated so that the change takes effect. But the app crashes.
How I deal with the fragments:
if (savedInstanceState == null) {
pageadapter = new SectionsPageAdapter(getSupportFragmentManager());
rFragMore = new RoomlistFragmentMore();
rFragMyRooms = new RoomlistFragmentMyRooms();
rFragFavs = new RoomlistFragmentFavorites();
} else {
rFragMyRooms = (RoomlistFragmentMyRooms)pageadapter.getItem(0);
rFragFavs = (RoomlistFragmentFavorites)pageadapter.getItem(1);
rFragMore = (RoomlistFragmentMore)pageadapter.getItem(2);
pageadapter.clearAdapter();
pageadapter = new SectionsPageAdapter(getSupportFragmentManager());
}
How I set up the Adapter:
private void setupViewPager(ViewPager viewPager) {
pageadapter.addFragment(rFragMyRooms, getResources().getString(R.string.myrooms));
pageadapter.addFragment(rFragFavs, getResources().getString(R.string.favorites));
pageadapter.addFragment(rFragMore, getResources().getString(R.string.more));
viewPager.setAdapter(pageadapter);
}
My Adapter:
public class SectionsPageAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
public void clearAdapter() {
mFragmentList.clear();
mFragmentTitleList.clear();
}
public SectionsPageAdapter(FragmentManager fm) {
super(fm);
}
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
#Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
#Override
public int getCount() {
return mFragmentList.size();
}
}
And the Error Log:
java.lang.NullPointerException: Attempt to invoke virtual method 'java.io.FileInputStream android.content.Context.openFileInput(java.lang.String)' on a null object reference
at com.yannick.mychatapp.RoomlistFragmentMore.readFromFile(RoomlistFragmentMore.java:246)
at com.yannick.mychatapp.RoomlistFragmentMore.addRoomToList(RoomlistFragmentMore.java:121)
at com.yannick.mychatapp.RoomlistFragmentMore.access$000(RoomlistFragmentMore.java:46)
at com.yannick.mychatapp.RoomlistFragmentMore$1.onDataChange(RoomlistFragmentMore.java:79)
at com.google.firebase.database.core.ValueEventRegistration.fireEvent(com.google.firebase:firebase-database##16.0.4:75)
at com.google.firebase.database.core.view.DataEvent.fire(com.google.firebase:firebase-database##16.0.4:63)
at com.google.firebase.database.core.view.EventRaiser$1.run(com.google.firebase:firebase-database##16.0.4:55)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
EDIT: the code of RoomlistFragmentMore
public class RoomlistFragmentMore extends Fragment {
private ListView listView;
private List<HashMap<String, String>> listItems = new ArrayList<>();
private String raumname, theme;
private static String userID = "";
private SimpleAdapter adapter;
private DatabaseReference root = FirebaseDatabase.getInstance().getReference().getRoot().child("rooms");
private ArrayList<Room> raumliste = new ArrayList<>();
private TextView keinraumgefunden;
private String[] kat;
private static final String TAG = "RoomlistFragmentMore";
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.roomlist_fragment_more,container,false);
listView = view.findViewById(R.id.listView);
keinraumgefunden = view.findViewById(R.id.keinraumgefunden);
kat = getResources().getStringArray(R.array.categories);
theme = readFromFile("mychatapp_theme.txt");
adapter = new SimpleAdapter(getActivity(), listItems, R.layout.listlayout,
new String[]{"name", "kat", "lock", "newest"},
new int[]{R.id.raumname, R.id.raumkat, R.id.raumlock, R.id.raumdatum});
listView.setAdapter(adapter);
root.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
addRoomToList(dataSnapshot);
}
#Override
public void onCancelled(DatabaseError databaseError) {
Toast.makeText(getActivity(), R.string.nodatabaseconnection, Toast.LENGTH_SHORT).show();
}
});
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
int position = listView.getPositionForView(view);
String roomname = listItems.get(position).values().toArray()[0].toString();
Room room = findRoom(raumliste, roomname);
request_password(room, position);
}
});
adapter.registerDataSetObserver(new DataSetObserver() {
#Override
public void onChanged() {
if (raumliste.isEmpty()) {
keinraumgefunden.setText(R.string.noroomfound);
} else {
keinraumgefunden.setText("");
}
}
});
return view;
}
private void addRoomToList(DataSnapshot dataSnapshot) {
HashMap<String, String> raeume = new HashMap<>();
raumliste.clear();
for(DataSnapshot uniqueKeySnapshot : dataSnapshot.getChildren()){
String name = uniqueKeySnapshot.getKey();
for(DataSnapshot roomSnapshot : uniqueKeySnapshot.getChildren()){
Room room = roomSnapshot.getValue(Room.class);
room.setRaumname(name);
if (!room.getPasswd().equals(readFromFile("mychatapp_raum_" + name + ".txt"))) {
raeume.put(name, kat[Integer.parseInt(room.getCaty())]+"/"+"\uD83D\uDD12"+"/");
raumliste.add(room);
}
break;
}
}
listItems.clear();
Iterator it = raeume.entrySet().iterator();
while (it.hasNext()){
HashMap<String, String> resultsMap = new HashMap<>();
Map.Entry pair = (Map.Entry)it.next();
resultsMap.put("name", pair.getKey().toString());
String daten = pair.getValue().toString();
String caty = daten.substring(0, daten.indexOf("/"));
String lock = daten.substring(daten.indexOf("/")+1, daten.lastIndexOf("/"));
String time = daten.substring(daten.lastIndexOf("/")+1, daten.length());
String newestTime = "";
int index = 0;
resultsMap.put("kat", caty);
resultsMap.put("lock", lock);
resultsMap.put("newest", newestTime);
if (time.equals("")) {
listItems.add(resultsMap);
} else {
listItems.add(index, resultsMap);
}
}
adapter.notifyDataSetChanged();
}
private void request_password(final Room room, final int position) {
LayoutInflater inflater = LayoutInflater.from(getContext());
View view = inflater.inflate(R.layout.enter_room, null);
raumname = room.getRaumname();
userID = readFromFile("mychatapp_userid.txt");
final EditText input_field = view.findViewById(R.id.room_password);
AlertDialog.Builder builder;
if (theme.equals(getResources().getStringArray(R.array.themes)[1])) {
builder = new AlertDialog.Builder(new ContextThemeWrapper(getActivity(), R.style.AlertDialogDark));
} else {
builder = new AlertDialog.Builder(getActivity());
}
builder.setTitle(R.string.pleaseenterpassword);
builder.setView(view);
builder.setCancelable(false);
builder.setPositiveButton(R.string.confirm, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
}
});
builder.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
View view = ((AlertDialog) dialogInterface).getCurrentFocus();
if (view != null) {
InputMethodManager imm = (InputMethodManager)getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
dialogInterface.cancel();
}
});
final AlertDialog alert = builder.create();
alert.setOnShowListener(new DialogInterface.OnShowListener() {
#Override
public void onShow(DialogInterface dialog) {
Button b = alert.getButton(AlertDialog.BUTTON_POSITIVE);
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (input_field.getText().toString().trim().equals(room.getPasswd())) {
Intent tabIntent = new Intent("tab");
LocalBroadcastManager.getInstance(getActivity()).sendBroadcast(tabIntent);
Intent intent = new Intent(getActivity(), ChatActivity.class);
intent.putExtra("room_name", room.getRaumname());
intent.putExtra("user_id",userID);
updateRoomList(position);
writeToFile(room.getPasswd(),"mychatapp_raum_" + raumname + ".txt");
alert.cancel();
startActivity(intent);
} else {
Toast.makeText(getActivity(), R.string.wrongpassword, Toast.LENGTH_SHORT).show();
}
}
});
}
});
alert.show();
}
public Room findRoom(ArrayList<Room> raumliste, String raumname) {
for (Room room : raumliste) {
if (room.getRaumname().equals(raumname)) {
return room;
}
}
return null;
}
public void writeToFile(String text, String datei) {
Context context = getActivity();
try {
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(context.openFileOutput(datei, Context.MODE_PRIVATE));
outputStreamWriter.write(text);
outputStreamWriter.close();
}
catch (IOException e) {
Log.e("Exception", "File write failed: " + e.toString());
}
}
public String readFromFile(String datei) {
Context context = getActivity();
String erg = "";
try {
InputStream inputStream = context.openFileInput(datei);
if ( inputStream != null ) {
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String receiveString = "";
StringBuilder stringBuilder = new StringBuilder();
while ( (receiveString = bufferedReader.readLine()) != null ) {
stringBuilder.append(receiveString);
}
inputStream.close();
erg = stringBuilder.toString();
}
}
catch (FileNotFoundException e) {
Log.e("login activity", "File not found: " + e.toString());
} catch (IOException e) {
Log.e("login activity", "Can not read file: " + e.toString());
}
return erg;
}
private void updateRoomList(int position) {
listItems.remove(position);
adapter.notifyDataSetChanged();
}
}
The NullPointerException occured while onDataChange() was executed (you can see this by reading the stack trace). More specifically, readFromFile() needs a valid Context to open a file.
Since your app crashed we know that getActivity() did return null. How can this happen?
You add the ValueEventListener in onCreateView(). At this point in time, the Fragment has a valid Context (see the documentation for an explanation of the Lifecycle), so all is well for the moment.
But since you do not remove the ValueEventListener, it will continue to fire even if the Fragment is temporarily not attached to the Activity because the user swiped to the next page. The Fragment won't be garbage collected because you keep it in a list and reuse it.
This approach is basically ok if you implement null checks to avoid accessing the Activity, the Context or Views in general while they are not present. Of course, you could consider a stronger separation of the data and the View layer as suggested in this guide to app architecture
I am developing an app in android studio in which contents are coming form an Api in a recyclerview. In the api there is an element "content" that sends all html tags with images like a full page. I have to display that page in textview. I have tried Htm.fromHtml method but it is not displaying the images. I have searched all answers and got the solution of ImageGetter method, but I am not able to display dynamic content in the recycleradapter from ImageGetter. I have to keep the images in the drawable of my app and match the source URL that is being parsed. Please help. Below is my code.
PageActivity.java
public class PageActivity extends AppCompatActivity {
RequestQueue queue;
String menuidpage;
RecyclerView recyclerView;
List<MenuFeeds> feedsList = new ArrayList<MenuFeeds>();
String newimage = "http://www.groveus.com/micro/assets/uploads/page/";
PageRecyclerAdapter adapter;
private ProgressDialog pDialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_page);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
Bundle bundle=getIntent().getExtras();
menuidpage=bundle.getString("page_id");
recyclerView = (RecyclerView) findViewById(R.id.recyclerviewpage);
pDialog = new ProgressDialog(this);
adapter = new PageRecyclerAdapter(this, feedsList);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(adapter);
//Getting Instance of Volley Request Queue
queue = NetworkController.getInstance(this).getRequestQueue();
//Volley's inbuilt class to make Json array request
pDialog.setMessage("Loding...");
pDialog.show();
String url = "http://www.groveus.com/micro/api/index.php/pages/view?
id="+menuidpage;
JsonArrayRequest menuReq = new JsonArrayRequest(url, new
Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
pDialog.dismiss();
for (int i = 0; i < response.length(); i++) {
try {
JSONObject obj = response.getJSONObject(i);
MenuFeeds feeds = new MenuFeeds(obj.getInt("page_id"),
obj.getString("status"), obj.getString("title"),
newimage+obj.getString("image"),obj.getString("content"));
// adding movie to movies array
feedsList.add(feeds);
} catch (Exception e) {
System.out.println(e.getMessage());
} finally {
//Notify adapter about data changes
adapter.notifyItemChanged(i);
}
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
System.out.println(error.getMessage());
pDialog.dismiss();
}
});
//Adding JsonArrayRequest to Request Queue
queue.add(menuReq);
}
#Override
public boolean onSupportNavigateUp() {
onBackPressed();
return true;
}
}
PageRecyclerAdapter.java
public class PageRecyclerAdapter extends
RecyclerView.Adapter<PageRecyclerAdapter.MyViewHolder> implements
View.OnTouchListener
{
private List<MenuFeeds> feedsList;
private Context context;
private LayoutInflater inflater;
public PageRecyclerAdapter(Context context, List<MenuFeeds> feedsList) {
this.context = context;
this.feedsList = feedsList;
inflater = (LayoutInflater)
context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View rootView = inflater.inflate(R.layout.list_layout5, parent, false);
return new MyViewHolder(rootView);
}
#RequiresApi(api = Build.VERSION_CODES.N)
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
final MenuFeeds feeds = feedsList.get(position);
//Pass the values of feeds object to Views
//holder.idmenu.setText(feeds.getMenuId());
//holder.title.setText(feeds.getFeedName());
/* holder.description.setText(Html.fromHtml(feeds.getDescription(), 0,
new Html.ImageGetter() {
#Override
public Drawable getDrawable(String s) {
int id;
if
(s.equals("http://www.groveus.com/micro/assets/images/URINARY TRACT
INFECTION 1.png")) {
id = R.drawable.urin1;
}
else if
(s.equals("http://www.groveus.com/micro/assets/images/URINARY TRACT
INFECTION 2.png")) {
id = R.drawable.urin2;
}
else if
(s.equals("http://www.groveus.com/micro/assets/images/SKIN AND SOFT TISSUE
INFECTION 1.png")) {
id = R.drawable.skinsoft1;
}
else if
(s.equals("http://www.groveus.com/micro/assets/images/SKIN AND SOFT TISSUE
INFECTION 2.png")) {
id = R.drawable.skinsoft2;
}
else if
(s.equals("http://groveus.com/micro/assets/images/RESPIRATORY TRACT
INFECTION.png")) {
id = R.drawable.respo;
}
else if (s.equals("http://groveus.com/micro/assets/images/LOCAL
BACTERIAL INFECTIONS.png")) {
id = R.drawable.local;
}
else if
(s.equals("http://groveus.com/micro/assets/images/URINARY TRACT INFECTION
2nd 1.png")) {
id = R.drawable.urine2nd1;
}
else if
(s.equals("http://groveus.com/micro/assets/images/URINARY TRACT INFECTION
2nd 2.png")) {
id = R.drawable.urine2nd2;
}
else if
(s.equals("http://groveus.com/micro/assets/images/table.png")) {
id = R.drawable.table;
}
else if
(s.equals("http://www.groveus.com/micro/assets/images/table 2.png")) {
id = R.drawable.table2;
}
else {
return null;
}
Drawable d = context.getResources().getDrawable(id);
d.setBounds(0,0,1020,600);
return d;
}
}, null));*/
holder.description.setText(Html.fromHtml(feeds.getDescription()));
holder.description.setOnTouchListener(this);
holder.description.setMovementMethod(new ScrollingMovementMethod());
holder.imageview.setImageUrl(feeds.getImgURL(),
NetworkController.getInstance(context).getImageLoader());
// holder.ratingbar.setProgress(feeds.getRating());
}
#Override
public int getItemCount() {
return feedsList.size();
}
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
view.getParent().requestDisallowInterceptTouchEvent(true);
return false;
}
public class MyViewHolder extends RecyclerView.ViewHolder {
private TextView title,description;
private NetworkImageView imageview;
//private ProgressBar ratingbar;
public MyViewHolder(View itemView) {
super(itemView);
title = (TextView) itemView.findViewById(R.id.ImageNameTextView);
description = (TextView) itemView.findViewById(R.id.desc);
//idmenu = (TextView) itemView.findViewById(R.id.ImageNameTextView2);
UrlImageParser p=new UrlImageParser(description,context);
// Volley's NetworkImageView which will load Image from URL
imageview = (NetworkImageView) itemView.findViewById(R.id.thumbnail);
}
}
}
MenuFeeds.java
public class MenuFeeds
{
private String imgURL, feedName, description,page;
//private String id;
private int id;
public MenuFeeds(int menuid, String page, String name, String imgurl,String
desc) {
this.id=menuid;
this.page=page;
this.feedName = name;
this.imgURL = imgurl;
this.description = desc;
//this.rating = rating;
}
public int getMenuId() {
return id;
}
public String getPageID()
{
return page;
}
public String getDescription() {
return description;
}
public String getImgURL() {
return imgURL;
}
public String getFeedName() {
return feedName;
}
}
I also faced a similar problem month ago and used this and it works fine :
String htmlData = listData.get(position).getValue();
String showData = htmlData.replace("\n", "");
URLImageParser p = new URLImageParser(holder.textt, context);
Spanned htmlAsSpanned = Html.fromHtml(showData,p,null);
holder.yourTextView.setText(htmlAsSpanned);
Now copy and paste these 2 methods :
First method :
public class URLDrawable extends BitmapDrawable {
protected Drawable drawable;
#Override
public void draw(Canvas canvas) {
if(drawable != null) {
drawable.draw(canvas);
}
}
}
///Second Method :
public class URLImageParser implements Html.ImageGetter {
Context c;
TextView container;
/***
* Construct the URLImageParser which will execute AsyncTask and refresh the container
* #param t
* #param c
*/
public URLImageParser(TextView t, Context c) {
this.c = c;
this.container = t;
}
public Drawable getDrawable(String source) {
URLDrawable urlDrawable = new URLDrawable();
// get the actual source
ImageGetterAsyncTask asyncTask =
new ImageGetterAsyncTask( urlDrawable);
asyncTask.execute(source);
// return reference to URLDrawable where I will change with actual image from
// the src tag
return urlDrawable;
}
public class ImageGetterAsyncTask extends AsyncTask<String, Void, Drawable> {
URLDrawable urlDrawable;
public ImageGetterAsyncTask(URLDrawable d) {
this.urlDrawable = d;
}
#Override
protected Drawable doInBackground(String... params) {
String source = params[0];
return fetchDrawable(source);
}
#Override
protected void onPostExecute(Drawable result) {
// set the correct bound according to the result from HTTP call
urlDrawable.setBounds(0, 0, 0 + result.getIntrinsicWidth(), 0
+ result.getIntrinsicHeight());
// change the reference of the current drawable to the result
// from the HTTP call
urlDrawable.drawable = result;
// redraw the image by invalidating the container
URLImageParser.this.container.invalidate();
URLImageParser.this.container.setHeight((URLImageParser.this.container.getHeight()
+ result.getIntrinsicHeight()));
}
/***
* Get the Drawable from URL
* #param urlString
* #return
*/
public Drawable fetchDrawable(String urlString) {
try {
InputStream is = fetch(urlString);
Drawable drawable = Drawable.createFromStream(is, "src");
drawable.setBounds(0, 0, 0 + drawable.getIntrinsicWidth(), 0
+ drawable.getIntrinsicHeight());
return drawable;
} `enter code here`catch (Exception e) {
return null;
}
}
private InputStream fetch(String urlString) throws MalformedURLException, IOException {
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpGet request = new HttpGet(urlString);
HttpResponse response = httpClient.execute(request);
return response.getEntity().getContent();
}
}
}
try this
load your image using piccaso
add below library in your build.gradle
implementation 'com.squareup.picasso:picasso:2.71828'
when you need to set image use piccaso this way
Picasso.get()
.load(your_image)
.placeholder(R.drawable.user_placeholder)
.error(R.drawable.your_error_image_or_blank)
.into(your_imageView);
I am working on an application in which i need to implement favorites using ROOM ORM. I have different Duas in a fragment and there is a button for inserting that Dua into the Database the insertion part works fine but when i try to load the dua by clicking on the dua which i had recently added to the favorite a null pointer exception is thrown and this only happens in the case when i add more then two duas to the favorite list at the same time. Code is attached have a look BELOW is the DAO CLASS
import android.arch.lifecycle.LiveData;
import android.arch.persistence.room.Dao;
import android.arch.persistence.room.Insert;
import android.arch.persistence.room.Query;
import com.islam.cheapapps.dua101.model.Favorite;
import java.util.List;
/**
* Created by home on 16/06/2018.
*/
#Dao
public interface FavoriteDao {
#Insert
void insert(Favorite favorite);
#Query("DELETE FROM favorite_dua")
void deleteAll();
//ORDER BY word ASC if ordering is necessary.(optional)
#Query("SELECT * from favorite_dua")
LiveData<List<Favorite>> getAllDuas();
#Query("SELECT * FROM favorite_dua WHERE position = :position AND dua_category = :dua_category")
Favorite getFavoritePosition(int position, String dua_category);
}
CLASS IN WHICH THE FAVORITE BUTTON IS CLICKED
public class ScreenSlidePageFragment extends Fragment {
JSONArray jsonArray;
FavoriteViewModel mWordViewModel;
// Variable for identification of category (0 for duas after salah, 1 for morning azkar) and so on
int id = 0;
private int pos = 0;
//Title Text View
private TextView headerTV;
//Pronunciation Text View
private TextView pronunciationTV;
//Translation Text View
private TextView translationTV;
//Benefit Text View
private TextView benefitTV;
//Reference Text View
private TextView referenceTV;
//Dua Image View
private ImageView duaIV;
//Favorite Button
private LikeButton favoriteBtn;
//Share Button
private SparkButton shareButton;
public void setPosition(int pos) {
this.pos = pos;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
ViewGroup rootView = (ViewGroup) inflater.inflate(
R.layout.dua_layout, container, false);
//Get reference to the dua title
headerTV = rootView.findViewById(R.id.title);
//Get reference to the dua pronunciation
pronunciationTV = rootView.findViewById(R.id.pronounciationTV);
//Get reference to the dua translation
translationTV = rootView.findViewById(R.id.translationTV);
//Get reference to the dua benefit
benefitTV = rootView.findViewById(R.id.benefitTV);
//Get reference to the dua reference
referenceTV = rootView.findViewById(R.id.referenceTV);
//Get reference to the dua img
duaIV = rootView.findViewById(R.id.duaIV);
//Get reference to the favorite Button
favoriteBtn = rootView.findViewById(R.id.favorite_btn);
//Get reference to the share Button
shareButton = rootView.findViewById(R.id.share_btn);
//Setting onClick Listener on share Button
shareButton.setEventListener(new SparkEventListener() {
#Override
public void onEvent(ImageView imageView, boolean b) {
}
#Override
public void onEventAnimationEnd(ImageView imageView, boolean b) {
}
#Override
public void onEventAnimationStart(ImageView imageView, boolean b) {
shareDua();
}
});
//Setting onClick listener on the fav button which will add the dua to favorite list.
favoriteBtn.setOnLikeListener(new OnLikeListener() {
#Override
public void liked(LikeButton likeButton) {
addToFavorites();
}
#Override
public void unLiked(LikeButton likeButton) {
}
});
// Function for getting data of a specific category
getData();
// Function for setting data into the view
setData();
mWordViewModel = ViewModelProviders.of(this).get(FavoriteViewModel.class);
return rootView;
}
// Getting Data for a specific category
private void getData() {
id = getActivity().getIntent().getIntExtra("position", 0);
switch (id) {
case 0:
readData(this.getResources().openRawResource(R.raw.c0));
break;
case 1:
readData(this.getResources().openRawResource(R.raw.c1));
break;
case 2:
readData(this.getResources().openRawResource(R.raw.c2));
break;
case 3:
readData(this.getResources().openRawResource(R.raw.c0));
break;
case 4:
readData(this.getResources().openRawResource(R.raw.c0));
break;
case 5:
readData(this.getResources().openRawResource(R.raw.c0));
break;
default:
break;
}
}
/**
* Reading data from the JSON array
*/
private void readData(InputStream in) {
StringBuilder text = new StringBuilder();
BufferedReader br = null;
try {
br = new BufferedReader((new InputStreamReader(in)));
String line;
while ((line = br.readLine()) != null) {
text.append(line);
text.append('\n');
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (br != null) {
br.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
try {
jsonArray = new JSONArray(text.toString());
} catch (JSONException e) {
e.printStackTrace();
}
}
/**
* Set Data depending upon the position of view pager
*/
private void setData() {
try {
JSONArray tempJson = jsonArray.getJSONArray(this.pos);
duaIV.setImageResource(getResources().getIdentifier(tempJson.getString(3).trim().substring(0, tempJson.getString(3).indexOf(".png")), "drawable", getActivity().getPackageName()));
headerTV.setText(tempJson.getString(0).trim());
pronunciationTV.setText(tempJson.getString(3).trim());
translationTV.setText(tempJson.getString(9).trim());
benefitTV.setText(tempJson.getString(12).trim());
referenceTV.setText(tempJson.getString(11).trim());
} catch (JSONException e) {
e.printStackTrace();
}
}
/**
* A share intent is fired and gives choice to user for sharing the current dua using the applications
* that are present in his mobile
*/
private void shareDua() {
/*try {
sharingText = mJsonArray.getJSONObject(currPos).getString("seq") + "\n" +
mJsonArray.getJSONObject(currPos).getString("narator") + "\n" +
mJsonArray.getJSONObject(currPos).getString("hadith");
} catch (JSONException e) {
e.printStackTrace();
}*/
Intent sharingIntent = new Intent();
sharingIntent.setAction(Intent.ACTION_SEND);
sharingIntent.setType("text/plain");
// sharingIntent.putExtra(Intent.EXTRA_TEXT, sharingText);
startActivity(Intent.createChooser(sharingIntent, "Share using"));
}
//Add dua to favorite on pressing the favorite button
private void addToFavorites() {
String dua_category = "";
switch (id) {
case 0:
dua_category = "Duas after Salah";
break;
case 1:
dua_category = "Morning Azkar";
break;
case 2:
dua_category = "Evening Azkar";
break;
case 3:
dua_category = "Rabbana Duas";
break;
case 4:
dua_category = "Essential Duas";
break;
case 5:
dua_category = "Ruquiya";
break;
default:
dua_category = "";
break;
}
Favorite favorite = new Favorite(headerTV.getText().toString(),
pronunciationTV.getText().toString(), dua_category, this.pos);
Toast.makeText(this.getContext().getApplicationContext(), "Position : " + this.pos + "Category : "
+ dua_category
, Toast.LENGTH_SHORT).show();
mWordViewModel.insert(favorite);
}
}
THE CLASS IN WHICH THE ONCLICK FOR FAVORITE ITEM WHEN THE ITEM IS ALREADY ADDED TO THE LIST IS IMPLEMENTED
public class FavoriteAdapter extends
RecyclerView.Adapter<FavoriteAdapter.MyViewHolder> {
private final LayoutInflater mInflater;
private Context mContext;
private List<Favorite> mDuas; // Cached copy of words
String cat = "";
public FavoriteAdapter(Context mContext) {
this.mContext = mContext;
mInflater = LayoutInflater.from(mContext);
}
#Override
public FavoriteAdapter.MyViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
View itemView = mInflater.inflate(R.layout.favorite_single_item, viewGroup, false);
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(FavoriteAdapter.MyViewHolder holder, int position) {
// Variable for holding the position of the current view that was clicked
final int temp = position;
if (mDuas != null) {
Favorite current = mDuas.get(position);
holder.favoriteHeader.setText(current.getHeader());
holder.favoritePronunciation.setText(current.getDua_pronunciation());
cat = current.getDua_category();
} else {
// Covers the case of data not being ready yet.
holder.favoriteHeader.setText("No Word");
}
holder.favoriteCV.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
new Thread(new Runnable() {
#Override
public void run() {
FavoriteRoomDatabase db = FavoriteRoomDatabase.getDatabase(mContext);
FavoriteDao mFavoriteDao = db.favoriteDao();
Favorite f = mFavoriteDao.getFavoritePosition(temp, cat);
////////////////////////// TEST LOGIC //////////////////////////////
Intent intent = new Intent(mContext, ScreenSlidePagerActivity.class);
intent.putExtra("fav", "favorite");
intent.putExtra("category", f.getDua_category());
intent.putExtra("position", f.getPosition());
mContext.startActivity(intent);
////////////////////////////////////////////////////////////////////
}
}).start();
}
});
}
public void setDuas(List<Favorite> duas) {
mDuas = duas;
notifyDataSetChanged();
}
#Override
public int getItemCount() {
if (mDuas != null) {
return mDuas.size();
} else {
return 0;
}
}
public class MyViewHolder extends RecyclerView.ViewHolder {
public TextView favoriteHeader, favoritePronunciation;
public ImageView favoriteImage;
public CardView favoriteCV;
public MyViewHolder(View itemView) {
super(itemView);
favoriteCV = itemView.findViewById(R.id.favoriteCV);
favoriteHeader = itemView.findViewById(R.id.favorite_header);
favoritePronunciation = itemView.findViewById(R.id.favorite_pronunciation);
favoriteImage = itemView.findViewById(R.id.favorite_image);
}
}
}
i have some problem with my JSON code.
I want to display a list that contain text and image. The text and image stored on my online database, i using JSON for taking them down to my android app.
The JSON doesn't display any error, the text are displayed but the image are not appear.
I check the logcat and there's no error for this process. I using viewAdapter for displaying the image on the list.
Please master help me, can you gimme some simple explanation how to solve this??
Thanks...
NB. This is my code for HomeFragment.java (where i doing the JSON).
public class HomeFragment extends Fragment implements InternetConnectionListener, ApiHandler.ApiHandlerListener {
private static final String ARG_SECTION_NUMBER = "section_number";
private final int CATEGORY_ACTION = 1;
private CategorySelectionCallbacks mCallbacks;
private ArrayList<Category> categoryList;
private ListView categoryListView;
private String Error = null;
private InternetConnectionListener internetConnectionListener;
public HomeFragment() {
}
public static HomeFragment newInstance(int sectionNumber) {
HomeFragment fragment = new HomeFragment();
Bundle args = new Bundle();
args.putInt(ARG_SECTION_NUMBER, sectionNumber);
fragment.setArguments(args);
return fragment;
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
((HomeActivity) activity).onSectionAttached(getArguments().getInt(ARG_SECTION_NUMBER));
try {
mCallbacks = (CategorySelectionCallbacks) activity;
} catch (ClassCastException e) {
throw new ClassCastException("Activity must implement CategorySelectionCallbacks.");
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_home, container, false);
categoryListView = (ListView) rootView.findViewById(R.id.categoryListView);
return rootView;
}
#Override
public void onResume() {
super.onResume();
if (UtilMethods.isConnectedToInternet(getActivity())) {
initCategoryList();
} else {
internetConnectionListener = (InternetConnectionListener) HomeFragment.this;
showNoInternetDialog(getActivity(), internetConnectionListener,
getResources().getString(R.string.no_internet),
getResources().getString(R.string.no_internet_text),
getResources().getString(R.string.retry_string),
getResources().getString(R.string.exit_string), CATEGORY_ACTION);
}
}
public class getCategList extends AsyncTask<Void, Void, Void>{
#Override
protected Void doInBackground(Void... params) {
/**
* json is populating from text file. To make api call use ApiHandler class
*
* <CODE>ApiHandler apiHandler = new ApiHandler(this, URL_GET_CATEGORY);</CODE> <BR>
* <CODE>apiHandler.doApiRequest(ApiHandler.REQUEST_GET);</CODE> <BR>
*
* You will get the response in onSuccessResponse(String tag, String jsonString) method
* if successful api call has done. Do the parsing as the following.
*/
URL hp = null;
try {
hp = new URL(
getString(R.string.liveurl) + "foodcategory.php");
Log.d("URL", "" + hp);
URLConnection hpCon = hp.openConnection();
hpCon.connect();
InputStream input = hpCon.getInputStream();
BufferedReader r = new BufferedReader(new InputStreamReader(input));
String x = "";
x = r.readLine();
String total = "";
while (x != null) {
total += x;
x = r.readLine();
}
Log.d("UR1L", "" + total);
JSONArray j = new JSONArray(total);
Log.d("URL1", "" + j.length());
categoryList = new ArrayList<Category>();
for (int i = 0; i < j.length(); i++) {
Category category = new Category();// buat variabel category
JSONObject Obj;
Obj = j.getJSONObject(i); //sama sperti yang lama, cman ini lebih mempersingkat karena getJSONObject cm d tulis sekali aja disini
category.setId(Obj.getString(JF_ID));
category.setTitle(Obj.getString(JF_TITLE));
category.setIconUrl(Obj.getString(JF_ICON));
if (!TextUtils.isEmpty(Obj.getString(JF_BACKGROUND_IMAGE))) {
category.setImageUrl(Obj.getString(JF_BACKGROUND_IMAGE));
}
Log.d("URL1",""+Obj.getString(JF_TITLE));
categoryList.add(category);
}
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
categoryListView.setAdapter(new CategoryAdapter(getActivity(), mCallbacks, categoryList));
}
});
}catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Error = e.getMessage();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Error = e.getMessage();
} catch (JSONException e) {
// TODO Auto-generated catch block
Error = e.getMessage();
e.printStackTrace();
} catch (NullPointerException e) {
// TODO: handle exception
Error = e.getMessage();
}
return null;
}
}
//! function for populate category list
private void initCategoryList() {
new getCategList().execute();
}
#Override
public void onConnectionEstablished(int code) {
if (code == CATEGORY_ACTION) {
initCategoryList();
}
}
#Override
public void onUserCanceled(int code) {
if (code == CATEGORY_ACTION) {
getActivity().finish();
}
}
//! catch json response from here
#Override
public void onSuccessResponse(String tag, String jsonString) {
//! do same parsing as done in initCategoryList()
}
//! detect response error here
#Override
public void onFailureResponse(String tag) {
}
//! callback interface listen by HomeActivity to detect user click on category
public static interface CategorySelectionCallbacks {
void onCategorySelected(String catID, String title);
}
}
This code for categoryAdapter.java (where i put the result of JSON to the list)
public class CategoryAdapter extends ArrayAdapter<Category> implements View.OnClickListener {
private final LayoutInflater inflater;
private final ArrayList<Category> categoryList;
private Activity activity;
private HomeFragment.CategorySelectionCallbacks mCallbacks;
private String dummyUrl = "http://www.howiwork.org";
AbsListView.LayoutParams params;
public CategoryAdapter(Activity activity, HomeFragment.CategorySelectionCallbacks mCallbacks, ArrayList<Category> categoryList) {
super(activity, R.layout.layout_category_list);
this.activity = activity;
this.inflater = LayoutInflater.from(activity.getApplicationContext());
this.categoryList = categoryList;
this.mCallbacks = mCallbacks;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder row;
if (convertView == null) {
convertView = inflater.inflate(R.layout.layout_category_list, null);
row = new ViewHolder();
row.bannerImage = (ImageView) convertView.findViewById(R.id.catBannerImageView);
row.categoryImage = (ImageView) convertView.findViewById(R.id.catImageView);
row.categoryName = (TextView) convertView.findViewById(R.id.catNameTV);
} else {
row = (ViewHolder) convertView.getTag();
}
Category category = categoryList.get(position);
Picasso.with(activity).load(UtilMethods
.getDrawableFromFileName(activity,category.getIconUrl()))
.tag(category.getIconUrl())
.into(row.categoryImage);
row.categoryName.setText(category.getTitle());
Picasso.with(activity)
.load(UtilMethods.getDrawableFromFileName(activity,category.getImageUrl()))
.placeholder(R.drawable.img_banner_placeholder)
.tag(category.getIconUrl())
.fit()
.into(row.bannerImage);
row.bannerImage.setOnClickListener(this);
row.categoryImage.setTag(position);
row.categoryName.setTag(position);
row.bannerImage.setTag(position);
return convertView;
}
#Override
public int getCount() {
return categoryList.size();
}
#Override
public void onClick(View v) {
int position = Integer.parseInt(v.getTag().toString());
mCallbacks.onCategorySelected(categoryList.get(position).getId(),
categoryList.get(position).getTitle());
}
private static class ViewHolder {
public ImageView bannerImage;
public TextView categoryName;
public ImageView categoryImage;
}
}
Try this.
Picasso.with(activity).load(category.getIconUrl())
.into(row.categoryImage);
If it worked !. You Check the UtilMethods.getDrawableFromFileName() !!!