In my sample project, I implemented the code using activity, running fine.
After then I implemented that code in my main App which is using Fragment.
For that I extends Fragment, made a default constructor, made onCreateView & inside that inflated the layout, then changed getApplicationContext() to getActivity(). Thats how I managed to remove errors in my main app.
An in my MainActivity this is how we update the main content by replacing fragments by calling constructor & assigning it to fragments:
/**
* Diplaying fragment view for selected nav drawer list item
* */
private void displayView(int position) {
// update the main content by replacing fragments
Fragment fragment = null;
switch (position) {
case 0:
fragment = new IntroductionFragment();
break;
case 1:
fragment = new PrefaceFragment();
break;
case 2:
fragment = new PreambleFragment();
break;
case 3:
fragment = new ContentsFragment();//ERROR here: because I modified this class
break;
case 4:
fragment = new SchedulesFragment();
break;
case 5:
fragment = new AppendixFragment();
break;
case 6:
fragment = new AmendmentFragment();
break;
case 7:
fragment = new PhotoFragment();
break;
default:
break;
}
if (fragment != null) {
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.frame_container, fragment).commit();
// update selected item and title, then close the drawer
mDrawerList.setItemChecked(position, true);
mDrawerList.setSelection(position);
setTitle(navMenuTitles[position]);
mDrawerLayout.closeDrawer(mDrawerList);
} else {
// error in creating fragment
Log.e("MainActivity", "Error in creating fragment");
}
}
That line shows me Type mismatch: cannot convert from ContentsFragment to Fragment
I hope the problem is clear. Please tell me how can I avoid this error...
This is ContentsFragment.java
public class ContentsFragment extends Fragment// implements OnTouchListener
{
public ContentsFragment() {
// TODO Auto-generated constructor stub
}
public static ArrayList<GS> q = new ArrayList<GS>();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
DBAdapter db = DBAdapter.getDBAdapter(getActivity());
if (!db.checkDatabase())
db.createDatabase(getActivity());
db.openDatabase();
q = db.getData();
// setContentView(R.layout.sample_activity);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v =inflater.inflate(R.layout.sample_activity, container, false);
final FloatingGroupExpandableListView list = (FloatingGroupExpandableListView) v.findViewById(R.id.sample_activity_list);
// final LayoutInflater inflater = getLayoutInflater();
// Even though the child divider has already been set on the layout file, we have to set it again here
// This prevents a bug where the background turns to the color of the child divider when the list is expanded
list.setChildDivider(new ColorDrawable(Color.BLACK));
final ArticlesAdapter adapter = new ArticlesAdapter(getActivity());
final WrapperExpandableListAdapter wrapperAdapter = new WrapperExpandableListAdapter(adapter);
list.setAdapter(wrapperAdapter);
for(int i = 0; i < wrapperAdapter.getGroupCount(); i++) {
list.collapseGroup(i);//expandGroup(i);
}
list.setOnScrollFloatingGroupListener(new FloatingGroupExpandableListView.OnScrollFloatingGroupListener() {
#Override
public void onScrollFloatingGroupListener(View floatingGroupView, int scrollY) {
float interpolation = - scrollY / (float) floatingGroupView.getHeight();
// Changing from RGB(162,201,85) to RGB(255,255,255)
final int greenToWhiteRed = (int) (0 + 3 * interpolation);
final int greenToWhiteGreen = (int) (0 + 6* interpolation);
final int greenToWhiteBlue = (int) ( 0+ 20 * interpolation);
final int greenToWhiteColor = Color.argb(200, greenToWhiteRed, greenToWhiteGreen, greenToWhiteBlue);
// Changing from RGB(255,255,255) to RGB(0,0,0)
final int whiteToBlackRed = (int) (255 - 1 * interpolation);
final int whiteToBlackGreen = (int) (255 - 1 * interpolation);
final int whiteToBlackBlue = (int) (255 - 1 * interpolation);
final int whiteToBlackColor = Color.argb(255, whiteToBlackRed, whiteToBlackGreen, whiteToBlackBlue);
final View background = floatingGroupView.findViewById(R.id.sample_activity_list_group_item_background);
background.setBackgroundColor(greenToWhiteColor);
final TextView text = (TextView) floatingGroupView.findViewById(R.id.sample_activity_list_group_item_text);
text.setTextColor(whiteToBlackColor);
final ImageView expanded = (ImageView) floatingGroupView.findViewById(R.id.sample_activity_list_group_expanded_image);
final Drawable expandedDrawable = expanded.getDrawable().mutate();
expandedDrawable.setColorFilter(whiteToBlackColor, PorterDuff.Mode.SRC_ATOP);
}
});
return v;
}
}
I think the problem is because of importing Fragment from different sources in two different classes ie. Your_Activity and ContentsFragment.java. One from android.support.v4.app.Fragment and one from android.app.Fragment.
Please make sure you are importing Fragment either from support library ie.android.support.v4.app.Fragment or from android.app.Fragment.
Related
I am developing an app which has a text message interface (something like Facebook Messenger, Whatsapp, etc). I want to be able to change the background color of all the chat bubbles (a ListView of TextViews) sent by the user when they pick a new color (in a NavigationView).
However, with the current code that I have, I only am able to change the color after the EditText used to compose the message is clicked again. Or I am able to only edit the first bubble sent, but as soon as the color is changed.
Here's what I tried :
ItemColor1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v){
Toast.makeText(activity, "Couleur mise à jour", Toast.LENGTH_SHORT).show();
currentTheme = position;
SharedPreferences.Editor editor = pref.edit();
editor.putInt("indexColorSelected",currentTheme);
editor.apply();
chatAdapter.notifyDataSetChanged();
//the following changes only the first message sent
for(int i=0; i<chatAdapter.getCount(); i++){
ChatData message = chatMessageList.get(position);
TextView msg = activity.findViewById(R.id.text);
msg.setText(message.body);
msg.setBackgroundResource(R.drawable.user_color1);
}
}
});
ChatData is a custom Class that I created which looks like this :
public class ChatAdapter extends BaseAdapter {
private static LayoutInflater inflater = null;
private ArrayList<ChatData> chatMessageList;
private Context mContext;
ChatAdapter(Activity activity, ArrayList<ChatData> list) {
mContext = activity;
chatMessageList = list;
inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
...
}
Color drawable:
<corners
android:bottomRightRadius="5dp"
android:radius="40dp"/>
<gradient
android:angle="45"
android:endColor="#01f1fa"
android:startColor="#0189ff"
android:type="linear" />
</shape>
getView() method of the Adapter:
public View getView(int position, View convertView, ViewGroup parent) {
ChatData message = chatMessageList.get(position);
View vi = convertView;
if (convertView == null)
vi = inflater.inflate(R.layout.msglist, parent, false);
TextView msg = vi.findViewById(R.id.text);
msg.setText(message.body);
LinearLayout layout = vi.findViewById(R.id.message_layout);
LinearLayout parent_layout = vi.findViewById(R.id.message_layout_parent);
inflater = (LayoutInflater) this.mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
// if message is mine then align to right
if (message.isMine) {
layout.setGravity(Gravity.RIGHT);
int couleurBubble = getCouleurSelectionnee();
switch(couleurBubble){
case R.color.c1: msg.setBackgroundResource(R.drawable.user_color1); break;
case R.color.c2: msg.setBackgroundResource(R.drawable.user_color2); break;
case R.color.c3: msg.setBackgroundResource(R.drawable.user_color3); break;
case R.color.c4: msg.setBackgroundResource(R.drawable.user_color4); break;
case R.color.c5: msg.setBackgroundResource(R.drawable.user_color5); break;
case R.color.c6: msg.setBackgroundResource(R.drawable.user_color6); break;
case R.color.c7: msg.setBackgroundResource(R.drawable.user_color7); break;
case R.color.c8: msg.setBackgroundResource(R.drawable.user_color8); break;
default: break;
}
parent_layout.setGravity(Gravity.RIGHT);
}
// If not mine then align to left
else {
layout.setGravity(Gravity.LEFT);
msg.setBackgroundResource(R.drawable.bot_chat);
parent_layout.setGravity(Gravity.LEFT);
}
return vi;
}
I don't really know where to go from here so any kind of help would be appreciated. If you want me to provide more code, let me know and I will.
Thank you.
I'm sharing how I would do it. Maybe, this can help you.
There's some strange issue because you are calling notifyDataSetChanged(). This would be enough to re-draw all message bubbles.
My ideia is:
Add a int variable to the adapter class (mColorResource). This variable will point to the proper drawable that should be used (like R.drawable.user_color1).
public class ChatAdapter extends BaseAdapter {
int mColorResource;
ChatAdapter(Activity activity, ArrayList<ChatData> list, int initialColorResource) {
mContext = activity;
chatMessageList = list;
inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
// You must receive the color on the construtor
mColorResource = initialColor;
}
// Use this method to update the color (when user select a new color)
public void setColor(int newColorResource) {
mColorResource = newColorResource;
}
public View getView(int position, View convertView, ViewGroup parent) {
...
// Note how this if-else is cleaner now
if (message.isMine) {
layout.setGravity(Gravity.RIGHT);
msg.setBackgroundResource(mColorResource);
parent_layout.setGravity(Gravity.RIGHT);
} else {
layout.setGravity(Gravity.LEFT);
msg.setBackgroundResource(R.drawable.bot_chat);
parent_layout.setGravity(Gravity.LEFT);
}
...
}
}
Then, when a color is selected, find the proper drawable based on the view clicked and pass it to the adapter:
ItemColor1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v){
Toast.makeText(activity, "Couleur mise à jour", Toast.LENGTH_SHORT).show();
currentTheme = position;
SharedPreferences.Editor editor = pref.edit();
editor.putInt("indexColorSelected", currentTheme);
editor.apply();
// Here, you send the proper drawable...
// I'm not sure how you convert color selected to the drawable
// So, add your logic to convert the button clicked to a drawable here
// like R.drawable.user_color1
chatAdapter.setColor(R.drawable.NAME_OF_THE_COLOR);
// Request to re-draw all items from the list (all bubbles)
chatAdapter.notifyDataSetChanged();
}
});
Also, on your activity, you create the adapter with the last used color. Something like:
#Override
protected void onCreate(#Nullable final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
....
// Set a default color (if user is open you app for the first time)
int chatColor = R.drawable.user_color1;
// Add your logic to read the shared preference and convert that last color used to a valid drawable.
// Like chatColor = pref.getInt(indexColorSelected, R.drawable.user_color1) etc....
// Set the color in the adapter.
chatAdapter = newAdapter(this, mChatDataList, chatColor);
}
I am implementing a Drag and Drop interface with 6 Drag TextViews and 6 Drop TextViews.
Any 1 of 6 Drag views can be dropped onto any 1 of 6 Drop views.
An example would be if tvNum1=13, tvNum2=16, tvNum3=9, then I can drop any one of them onto tvSTR, tvDEX, or tvINT and set the respective Drop text to whatever was dragged. So if tvNum2 was dragged onto tvSTR, then tvSTR should show 16. Or let's say that instead you decided to drag tvNum3 onto tvSTR, then tvSTR should show 9. Each Drag view can only be used once.
Here's my current code. I can't find a way to make it so that the text of whatever was dragged is the text of the Drop view. I can only make (a 1-to-1 correlation) it so that if tvNum1 was dragged onto tvSTR, then tvSTR=13. Or if tvNum2 was dragged onto tvDEX, then tvDEX=16.
public class setCharacterRolls extends AppCompatActivity
{
// Variable declarations
private TextView tvNum1, tvNum2, tvNum3, tvNum4, tvNum5, tvNum6;
private TextView tvSTR, tvDEX, tvINT, tvWIS, tvCHA, tvCON;
String roll1, roll2, roll3, roll4, roll5, roll6;
// String roll1Num, roll2Num, roll3Num, roll4Num, roll5Num, roll6Num;
private Button bSubmit;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_set_character_rolls);
// Get the previous intent
Intent intent = getIntent();
// Save the rolls from the previous screen onto a String to use later.
roll1 = intent.getStringExtra("roll1");
roll2 = intent.getStringExtra("roll2");
roll3 = intent.getStringExtra("roll3");
roll4 = intent.getStringExtra("roll4");
roll5 = intent.getStringExtra("roll5");
roll6 = intent.getStringExtra("roll6");
// Get TextView id's
tvNum1 = (TextView) findViewById(R.id.tDrag1);
tvNum2 = (TextView) findViewById(R.id.tDrag2);
tvNum3 = (TextView) findViewById(R.id.tDrag3);
tvNum4 = (TextView) findViewById(R.id.tDrag4);
tvNum5 = (TextView) findViewById(R.id.tDrag5);
tvNum6 = (TextView) findViewById(R.id.tDrag6);
tvSTR = (TextView) findViewById(R.id.tvSTR);
tvDEX = (TextView) findViewById(R.id.tvDEX);
tvINT = (TextView) findViewById(R.id.tvINT);
tvWIS = (TextView) findViewById(R.id.tvWIS);
tvCHA = (TextView) findViewById(R.id.tvCHA);
tvCON = (TextView) findViewById(R.id.tvCON);
// Set TextView to the roll numbers
tvNum1.setText(roll1);
tvNum2.setText(roll2);
tvNum3.setText(roll3);
tvNum4.setText(roll4);
tvNum5.setText(roll5);
tvNum6.setText(roll6);
// Set TextView to be draggable
tvNum1.setOnTouchListener(onTouch);
tvNum2.setOnTouchListener(onTouch);
tvNum3.setOnTouchListener(onTouch);
tvNum4.setOnTouchListener(onTouch);
tvNum5.setOnTouchListener(onTouch);
tvNum6.setOnTouchListener(onTouch);
// Targets to be dropped on
tvSTR.setOnDragListener(dragListener);
tvDEX.setOnDragListener(dragListener);
tvINT.setOnDragListener(dragListener);
tvWIS.setOnDragListener(dragListener);
tvCHA.setOnDragListener(dragListener);
tvCON.setOnDragListener(dragListener);
}
View.OnTouchListener onTouch = new View.OnTouchListener()
{
#Override
public boolean onTouch(View v, MotionEvent mEvent)
{
ClipData data = ClipData.newPlainText("", "");
View.DragShadowBuilder shadowBuild = new View.DragShadowBuilder(v);
v.startDrag(data, shadowBuild, v, 0);
return true;
}
};
View.OnDragListener dragListener = new View.OnDragListener()
{
#Override
public boolean onDrag(View v, DragEvent event)
{
int dragEvent = event.getAction();
switch(dragEvent)
{
case DragEvent.ACTION_DRAG_STARTED:
break;
case DragEvent.ACTION_DRAG_EXITED:
break;
case DragEvent.ACTION_DRAG_ENTERED:
final View view = (View) event.getLocalState();
switch(view.getId())
{
// This is where I have the 1-to-1 correlation.
// I want to be able to drag any draggable texview and set it to whatever it was dropped on.
case R.id.tDrag1:
tvSTR.setText(roll1);
break;
case R.id.tDrag2:
tvDEX.setText(roll2);
break;
default:
break;
}
break;
case DragEvent.ACTION_DROP:
break;
case DragEvent.ACTION_DRAG_ENDED:
break;
default:
break;
}
return true;
}
};
}
Hello how do I select a specific data in a list?
I have this list
for example I clicked on Kaiser (which is not in first nor last in the list)
I set this on the fragment
name.setText(obj.getName());
but the one that shows up is Mogul (which is the last on the list)
so how do I select the name specifically? any ideas?
edit:
here's the fragment and adapter
public class LivestockDetailFragment extends Fragment {
private Livestock livestock;
private View view;
private ImageButton pencil;
private EditText name;
private ImageButton save;
public static LivestockDetailFragment newInstance(Livestock livestock) {
LivestockDetailFragment fragment = new LivestockDetailFragment();
Bundle bundle = new Bundle();
bundle.putSerializable(DVBoerConstants.DV_LIVESTOCK_EXTRA, livestock);
fragment.setArguments(bundle);
return fragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//Inflate the layout for this fragment_packages
view = inflater.inflate(R.layout.fragment_livestock_detail, container, false);
livestock = (Livestock) getArguments().getSerializable(DVBoerConstants.DV_LIVESTOCK_EXTRA);
//initLivestockDetailsView(view);
initializeEdit();
ViewPager pager = (ViewPager) view.findViewById(R.id.viewPager);
pager.setAdapter(new MyPagerAdapter(getActivity().getSupportFragmentManager()));
name.setText(livestock.getName());
return view;
}
private class MyPagerAdapter extends FragmentPagerAdapter {
public MyPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int pos) {
switch(pos) {
case 0: return LivestockDetailPageFragment.newInstance(livestock);
case 1: return LivestockMedicalHistoryPageFragment.newInstance(livestock);
case 2: return LivestockGalleryPageFragment.newInstance(livestock);
default: return LivestockDetailPageFragment.newInstance(livestock);
}
}
#Override
public int getCount() {
return 3;
}
private String tabtitles[] = new String[]{"Details", "Medical History", "Gallery"};
Context context;
#Override
public CharSequence getPageTitle(int position) {
return tabtitles[position];
}
}
/*RecyclerView recyclerView = (RecyclerView)view.findViewById(R.id.livestock_detail_recycler_view);
recyclerView.setHasFixedSize(true);
RecyclerView.LayoutManager layoutManager = new GridLayoutManager(getActivity(),1);
recyclerView.setLayoutManager(layoutManager);
LivestockDetailAdapter adapter = new LivestockDetailAdapter(getActivity(), livestock);
recyclerView.setAdapter(adapter);*/
private void initializeEdit(){
pencil = (ImageButton) view.findViewById(R.id.editName);
name = (EditText) view.findViewById(R.id.nameTextView);
save = (ImageButton) view.findViewById(R.id.saveName);
save.setOnClickListener(buttonList);
pencil.setOnClickListener(buttonList);
}
private View.OnClickListener buttonList = new View.OnClickListener(){
public void onClick(View view) {
switch (view.getId()){
case R.id.editName:
save.setVisibility(View.VISIBLE);
name.setFocusableInTouchMode(true);
KeyboardUtility.openKeyboard(getActivity());
pencil.setVisibility(View.INVISIBLE);
break;
case R.id.saveName:
pencil.setVisibility(View.VISIBLE);
name.setFocusableInTouchMode(false);
name.setFocusable(false);
save.setVisibility(View.INVISIBLE);
KeyboardCloseUtility.hideKeyboard(getActivity());
break;
}
}
};
}
for every list, there's an index and you can get your specific item from index list. In your case you can also get the position from that list.
Based on your comment i guess you are not creating new object everytime .. if you are looping through array put Object generation code inside of loop. if thats not the case i cant help without looking at code
Looking at you problem, there can be two problems that I can see.:
you are not initializing your obj every time before adding it to the List.
Example: List<Object> lst= new ArrayList<Object>();
Object obj = new Object();
obj.setParam();
list.add();
obj.setparam();
list.add();
In this example before every setParam() you must do obj = new Object();
Otherwise every time you will be setting same Param to all the obj and
that param will be none other than the last one. So every list.add();
will add same object to the list.
you added obj outside of a loop in which you are setting the parameters
(all the names) so it will add only the last object to the list.
example:Object obj =null;
while(some condition is true){
obj = new object();
obj.setParam();
}
lst.add(obj);
In this example you might initialize obj every time but you are adding
only last obj to the list. Here you will have to put lst.add(obj);
inside the loop.
I hope your case is among these only.
I am looking for a way to have an "Are you sure you have finished?" alert box to come up when the user presses the back navigation button whilst on the edit note and add note fragment but not whilst they're on the view note fragment. Below I have attached code from the activity which each fragment is linked to. If you need more of my code from different areas, please let me know.
public class NoteDetailActivity extends AppCompatActivity {
public static final String NEW_NOTE_EXTRA = "New Note";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_note_detail);
createAndFragment();
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
getSupportActionBar().setHomeButtonEnabled(false);
}
private void createAndFragment(){
Intent intent = getIntent();
MainActivity.FragmentToLaunch fragmentToLaunch = (MainActivity.FragmentToLaunch) intent.getSerializableExtra(MainActivity.NOTE_FRAGMENT_TO_LOAD_EXTRA);
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
switch(fragmentToLaunch){
case EDIT:
NoteEditFragment noteEditFragment = new NoteEditFragment();
setTitle(R.string.edit_fragment_title);
fragmentTransaction.add(R.id.note_container, noteEditFragment, "NOTE_EDIT_FRAGMENT");
break;
case VIEW:
NoteViewFragment noteViewFragment = new NoteViewFragment();
setTitle(R.string.view_fragment_title);
fragmentTransaction.add(R.id.note_container, noteViewFragment, "NOTE_VIEW_FRAGMENT");
break;
case CREATE:
NoteEditFragment noteCreateFragment = new NoteEditFragment();
setTitle(R.string.create_fragment_title);
Bundle bundle = new Bundle();
bundle.putBoolean(NEW_NOTE_EXTRA, true);
noteCreateFragment.setArguments(bundle);
fragmentTransaction.add(R.id.note_container, noteCreateFragment, "NOTE_CREATE_FRAGMENT");
break;
}
fragmentTransaction.commit();
}
#Override
public void onBackPressed() {
new AlertDialog.Builder(this)
.setMessage("Are you sure you want to exit?")
.setCancelable(false)
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
NoteDetailActivity.this.finish();
}
})
.setNegativeButton("No", null)
.show();
}
}
Do this by getting the fragment tag
get tag like this
Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.main_container);
String tag = fragment.getTag(); // This will return the tag of fragment
Then use if-else to do the task
if (tag.equalsIgnoreCase("Home")) {
// Open aLERT box
}else if (tag.equalsIgnoreCase("Home2")) {
// Open aLERT box
}else if (tag.equalsIgnoreCase("Home2")) {
// Open aLERT box
}else{
// dO STUFF HERE
}
Don't forget to add the tag of fragment
First of all, try refraining from taking static tags as the names of fragment. Instead,you can set fragment's name as ABCFragment.class.getSimpleName().
Now for the checks on dialogs, create a method
/**
* This method is used to get the top fragmnet on the stack
*
* #return {#link Fragment}
*/
protected final Fragment getTopFragmentStack() {
FragmentManager fm = getSupportFragmentManager();
Fragment fragment = null;
for (int entry = 0; entry < fm.getBackStackEntryCount(); entry++) {
fragment = fm.findFragmentByTag(fm.getBackStackEntryAt(entry)
.getName());
}
return fragment;
}
After this to check which fragment is visible at the moment, you can use the following code
Fragment topRunningFragment = getTopFragmentStack();
if (topRunningFragment instanceof ABCFragment) {
showDialog();
} else if (topRunningFragment instanceof ABCDFragment) {
showDialog();
} else if (topRunningFragment instanceof ABCDEFragment) {
// Do nothing
}
I have a TextView[] object and a String[] field in a Fragment. I have 5 Fragments in total, all handled by a ViewPager. I want to retrieve pretty much all of the Strings displayed in each Fragment (and save it to a text file later) from the click of the parent activity's menu.
Anyway, here is some code:
This is within the main Activity (only working on retrieving data from first fragment):
private Intent createShareIntent() {
DisplayFragment displayFragment = (DisplayFragment) mAdapter.getItem(2);
Intent shareIntent = new Intent(android.content.Intent.ACTION_SEND);
shareIntent.setType("text/plain");
shareIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
// Add data to the intent, the receiving app will decide what to do
// with it.
shareIntent.putExtra(Intent.EXTRA_SUBJECT, "Display Info");
shareIntent.putExtra(Intent.EXTRA_TEXT, displayFragment.retrieveContent());
return shareIntent;
}
The NullPointerException comes from this method within DisplayFragment:
public class DisplayFragment extends Fragment {
static String devDensity, devDensityCategory, devDpi, devXDpi, devYDpi,
devPxWidth, devPxHeight, devRefreshRate, devOrientation;
static TextView tvDispDensity, tvDensityCategory, tvDispDpi, tvDispXDpi,
tvDispYDpi, tvDispPxWidth, tvDispPxHeight, tvDispRefreshRate,
tvOrientation;
DisplayMetrics metrics;
// For sharing information via e-mail/SMS
/**
* Final Content of display info
*/
String displayInfoContent;
/**
* All textviews used in for-loop to getText()
*/
private TextView[] textViews;
private String[] strings;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.display, container, false);
return rootView;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
metrics = new DisplayMetrics();
getActivity().getWindowManager().getDefaultDisplay()
.getMetrics(metrics);
devDensity = String.valueOf(metrics.density);
devDpi = String.valueOf(metrics.densityDpi);
devXDpi = String.valueOf(metrics.xdpi);
devYDpi = String.valueOf(metrics.ydpi);
devPxWidth = String.valueOf(metrics.widthPixels);
devPxHeight = String.valueOf(metrics.heightPixels);
devRefreshRate = String.valueOf(getActivity().getWindowManager()
.getDefaultDisplay().getRefreshRate());
translate();
// Displays
tvDispDensity = (TextView) getView()
.findViewById(R.id.tvDisplayDensity);
tvDispDensity.setText(devDensity);
tvDensityCategory = (TextView) getView().findViewById(
R.id.tvDensityCategory);
tvDensityCategory.setText(devDensityCategory);
tvDispDpi = (TextView) getView().findViewById(R.id.tvDisplayDpi);
tvDispDpi.setText(devDpi);
tvDispXDpi = (TextView) getView().findViewById(R.id.tvDisplayXDpi);
tvDispXDpi.setText(devXDpi);
tvDispYDpi = (TextView) getView().findViewById(R.id.tvDisplayYDpi);
tvDispYDpi.setText(devYDpi);
tvDispPxWidth = (TextView) getView()
.findViewById(R.id.tvDisplayWidthPx);
tvDispPxWidth.setText(devPxWidth + " px");
tvDispPxHeight = (TextView) getView().findViewById(
R.id.tvDisplayHeightPx);
tvDispPxHeight.setText(devPxHeight + " px");
tvDispRefreshRate = (TextView) getView().findViewById(
R.id.tvDisplayRefreshRate);
tvDispRefreshRate.setText(devRefreshRate + " Hz");
tvOrientation = (TextView) getView().findViewById(
R.id.tvDisplayOrientation);
tvOrientation.setText(devOrientation);
//
// #################################
textViews = new TextView[]{tvDispDensity, tvDensityCategory, tvDispDpi, tvDispXDpi,
tvDispYDpi, tvDispPxWidth, tvDispPxHeight, tvDispRefreshRate,
tvOrientation};
strings = new String[]{devDensity, devDensityCategory, devDpi, devXDpi, devYDpi,
devPxWidth, devPxHeight, devRefreshRate, devOrientation};
}
private void translate() {
switch (metrics.densityDpi) {
case DisplayMetrics.DENSITY_LOW:
devDensityCategory = "Low (120 dpi)";
break;
case DisplayMetrics.DENSITY_MEDIUM:
devDensityCategory = "Medium (160 dpi)";
break;
case DisplayMetrics.DENSITY_HIGH:
devDensityCategory = "High (240 dpi)";
break;
case DisplayMetrics.DENSITY_XHIGH:
devDensityCategory = "XHigh (320 dpi)";
break;
case DisplayMetrics.DENSITY_XXHIGH:
devDensityCategory = "XXHigh (480 dpi)";
break;
case DisplayMetrics.DENSITY_XXXHIGH:
devDensityCategory = "XXXHigh (640 dpi)";
break;
case DisplayMetrics.DENSITY_TV:
devDensityCategory = "TV (213 dpi)";
break;
case DisplayMetrics.DENSITY_400:
devDensityCategory = "Intermediate (400 dpi)";
break;
default:
devDensityCategory = "Unknown";
break;
}
switch (getActivity().getWindowManager().getDefaultDisplay()
.getRotation()) {
case Surface.ROTATION_0:
devOrientation = "0°";
break;
case Surface.ROTATION_90:
devOrientation = "90°";
break;
case Surface.ROTATION_180:
devOrientation = "180°";
break;
case Surface.ROTATION_270:
devOrientation = "270°";
break;
default:
devOrientation = "Unknown";
break;
}
}
public String retrieveContent() {
String content = "";
for (int i = 0; i < textViews.length; i++) {
content += (textViews[i].getText() + " = " + strings[i] + "\n");
}
return content;
}
Are the Arrays initialized when the Fragment is off-screen? If not, how could I pull this off otherwise?
Logcat:
java.lang.NullPointerException
at my.package.name.fragments.DisplayFragment.retrieveContent(DisplayFragment.java:170)
which is this content += (textViews[i].getText() + " = " + strings[i] + "\n"); in my for loop.
Any insight will be greatly appreciated, thank you for reading.
Regards,
Matt
Are the Arrays initialized when the Fragment is off-screen? If not, how could I pull this off otherwise?
The problem is when the Fragment is off-screen, the fragment itself might not have been created at all. By default, the view pager only initialize the previous and next page of the current page. For example, if you are active on page 1, only page 2 will be initialized by default. if you are on third page, then only 2nd, 3rd and 4th pages are created.
To pull this of otherwise? you can just simply set the off screen page limit to 4, so that it will make sure that it will keep 4 pages next or previous of your current page (in your case, all 5 fragments will be created at once)
urViewPager.setOffscreenPageLimit(4);
put that code in the OnCreate on the activity after your initialization of urViewPager.
Hope this helps, cheer.
I found the culprit. Apparently the TextView[] was not initialized properly. Insted of having it in OnActivityCreated(), I initialized TextView[] and String[] directly in retrieveInfo() method of fragment. Also made textview fields static variables and works like a charm
public String retrieveContent() {
textViews = new TextView[]{tvDispDensity, tvDensityCategory, tvDispDpi, tvDispXDpi,
tvDispYDpi, tvDispPxWidth, tvDispPxHeight, tvDispRefreshRate,
tvOrientation};
strings = new String[]{devDensity, devDensityCategory, devDpi, devXDpi, devYDpi,
devPxWidth, devPxHeight, devRefreshRate, devOrientation};
String content = "";
for (int i = 0; i < textViews.length; i++) {
content += (textViews[i].getText() + " = " + strings[i] + "\n");
}
return content;
}
Works just fine now :)