Intro:
My client require some components across the application like navigationDrawer, toolbar. So I have a MainActivity having two toolbar(top/bottom) and two navigation drawer(left/right). All other screens consist of fragments that I change in MainActivity. I have a little problem that is some of the action are being duplicated.
Cases:
In some fragments when user perform an action i.e.
1: User press "Add To Cart" button and press home button that is in toolbar Bottom, the code of "Add To Cart" button run twice (once clicking button, once going to home screen) so my item is being added to cart twice.
2: In another fragment I have "apply coupon" checkbox when user check that checkbox an AlertDialog appear and when user go to home screen the AlertDialog again appear in the home screen.
I'm simply recreating the main activity on home button press with recreate();
I check the code but can't understand why those actions duplicate. If someone faced the same or a bit similar problem please guide me how to tackle that. Any help would be appreciated.
If I need to show code tell me which part?
Edit:
inside onCreateView of fragment Cart Detail
useCoupon.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
createAndShowCustomAlertDialog();
}
}
});
Sequence of this code is Main Activity(Main Fragment)=>Product Frag=>Cart Detail Frag.
Edit 2: MainActivity
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
this.utils = new Utils(this);
utils.changeLanguage("en");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initViews();
this.context = this;
setupToolbar(this);
utils.switchFragment(new MainFrag());
setOnClickListener();
initRightMenuData();
initLeftMenuData();
listAdapter = new ExpandableListAdapter(headerListLeft, hashMapLeft,
false, loggedInIconList);
listViewExpLeft.setAdapter(listAdapter);
if (isLoggedIn()) {
listAdapterRight = new ExpandableListAdapterRight(headerListRight, hashMapRight,
loggedInIconList);
} else {
listAdapterRight = new ExpandableListAdapterRight(headerListRight, hashMapRight,
NotLoggedInIconList);
}
listViewExpRight.setAdapter(listAdapterRight);
enableSingleSelection();
setExpandableListViewClickListener();
setExpandableListViewChildClickListener();
}
private void setOnClickListener() {
myAccountTV.setOnClickListener(this);
checkoutTV.setOnClickListener(this);
discountTV.setOnClickListener(this);
homeTV.setOnClickListener(this);
searchIcon.setOnClickListener(this);
cartLayout.setOnClickListener(this);
}
private void setExpandableListViewClickListener() {
listViewExpRight.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {
#Override
public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition,
long id) {
utils.printLog("GroupClicked", " Id = " + id);
int childCount = parent.getExpandableListAdapter().getChildrenCount(groupPosition);
if (!isLoggedIn()) {
if (childCount < 1) {
if (groupPosition == 0) {
utils.switchFragment(new FragLogin());
} else if (groupPosition == 1) {
utils.switchFragment(new FragRegister());
} else if (groupPosition == 2) {
utils.switchFragment(new FragContactUs());
} else {
recreate();
}
drawer.closeDrawer(GravityCompat.END);
}
} else {
if (childCount < 1) {
changeFragment(103 + groupPosition);
drawer.closeDrawer(GravityCompat.END);
}
}
return false;
}
});
listViewExpLeft.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {
#Override
public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) {
int childCount = parent.getExpandableListAdapter().getChildrenCount(groupPosition);
if (childCount < 1) {
MenuCategory textChild = (MenuCategory) parent.getExpandableListAdapter()
.getGroup(groupPosition);
moveToProductFragment(textChild.getMenuCategoryId());
utils.printLog("InsideChildClick", "" + textChild.getMenuCategoryId());
}
return false;
}
});
}
private void setExpandableListViewChildClickListener() {
listViewExpLeft.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
#Override
public boolean onChildClick(ExpandableListView parent, View v, int groupPosition,
int childPosition, long id) {
MenuSubCategory subCategory = (MenuSubCategory) parent.getExpandableListAdapter()
.getChild(groupPosition, childPosition);
moveToProductFragment(subCategory.getMenuSubCategoryId());
utils.printLog("InsideChildClick", "" + subCategory.getMenuSubCategoryId());
return true;
}
});
listViewExpRight.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
#Override
public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
String str = parent.getExpandableListAdapter().getGroup(groupPosition).toString();
UserSubMenu userSubMenu = (UserSubMenu) parent.getExpandableListAdapter()
.getChild(groupPosition, childPosition);
if (str.contains("Information") || str.contains("معلومات")) {
Bundle bundle = new Bundle();
bundle.putString("id", userSubMenu.getUserSubMenuCode());
utils.switchFragment(new FragShowText(), bundle);
} else if (str.contains("اللغة") || str.contains("Language")) {
recreate();
} else if (str.contains("دقة") || str.contains("Currency")) {
makeDefaultCurrencyCall(userSubMenu.getUserSubMenuCode());
}
utils.printLog("InsideChildClick", "" + userSubMenu.getUserSubMenuCode());
drawer.closeDrawer(GravityCompat.END);
return false;
}
});
}
private void setupToolbar(Context context) {
ViewCompat.setLayoutDirection(appbarBottom, ViewCompat.LAYOUT_DIRECTION_RTL);
ViewCompat.setLayoutDirection(appbarTop, ViewCompat.LAYOUT_DIRECTION_RTL);
String imgPath = Preferences
.getSharedPreferenceString(appContext, LOGO_KEY, DEFAULT_STRING_VAL);
utils.printLog("Product Image = " + imgPath);
if (!imgPath.isEmpty()) {
Picasso.with(getApplicationContext()).load(imgPath)
.into(logoIcon);
}
logoIcon.setOnClickListener(this);
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
actionbarToggle();
drawer.addDrawerListener(mDrawerToggle);
drawerIconLeft.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
drawer.openDrawer(GravityCompat.START);
drawerIconLeft.setScaleX(1);
drawerIconLeft.setImageResource(R.drawable.ic_arrow_back_black);
}
}
});
drawerIconRight.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (drawer.isDrawerOpen(GravityCompat.END)) {
drawer.closeDrawer(GravityCompat.END);
} else {
drawer.openDrawer(GravityCompat.END);
}
}
});
}
private void initViews() {
drawerIconLeft = findViewById(R.id.drawer_icon_left);
drawerIconRight = findViewById(R.id.drawer_icon_right);
logoIcon = findViewById(R.id.logo_icon);
searchIcon = findViewById(R.id.search_icon);
cartLayout = findViewById(R.id.cart_layout);
counterTV = findViewById(R.id.actionbar_notification_tv);
drawer = findViewById(R.id.drawer_layout);
listViewExpLeft = findViewById(R.id.expandable_lv_left);
listViewExpRight = findViewById(R.id.expandable_lv_right);
appbarBottom = findViewById(R.id.appbar_bottom);
appbarTop = findViewById(R.id.appbar_top);
myAccountTV = findViewById(R.id.my_account_tv);
discountTV = findViewById(R.id.disc_tv);
checkoutTV = findViewById(R.id.checkout_tv);
homeTV = findViewById(R.id.home_tv);
searchView = findViewById(R.id.search_view);
}
#Override
public void onBackPressed() {
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else if (drawer.isDrawerOpen(GravityCompat.END)) {
drawer.closeDrawer(GravityCompat.END);
} else {
super.onBackPressed();
}
}
private void initRightMenuData() {
headerListRight = new ArrayList<>();
hashMapRight = new HashMap<>();
String[] notLoggedInMenu = {findStringByName("login_text"),
findStringByName("action_register_text"),
findStringByName("contact_us_text")};
String[] loggedInMenu = {findStringByName("account"), findStringByName("edit_account_text"),
findStringByName("action_change_pass_text"),
findStringByName("order_history_text"),
findStringByName("logout"), findStringByName("contact_us_text")};
List<UserSubMenu> userSubMenusList = new ArrayList<>();
if (isLoggedIn()) {
for (int i = 0; i < loggedInMenu.length; i++) {
headerListRight.add(loggedInMenu[i]);
hashMapRight.put(headerListRight.get(i), userSubMenusList);
}
} else {
for (int i = 0; i < notLoggedInMenu.length; i++) {
headerListRight.add(notLoggedInMenu[i]);
hashMapRight.put(headerListRight.get(i), userSubMenusList);
}
}
String responseStr = "";
if (getIntent().hasExtra(KEY_EXTRA)) {
responseStr = getIntent().getStringExtra(KEY_EXTRA);
utils.printLog("ResponseInInitData", responseStr);
try {
JSONObject responseObject = new JSONObject(responseStr);
boolean success = responseObject.optBoolean("success");
if (success) {
try {
JSONObject homeObject = responseObject.getJSONObject("home");
JSONArray slideshow = homeObject.optJSONArray("slideshow");
AppConstants.setSlideshowExtra(slideshow.toString());
JSONArray menuRight = homeObject.optJSONArray("usermenu");
for (int z = 0; z < menuRight.length(); z++) {
List<UserSubMenu> userSubMenuList = new ArrayList<>();
JSONObject object = menuRight.getJSONObject(z);
headerListRight.add(object.optString("name"));
JSONArray childArray = object.optJSONArray("children");
for (int y = 0; y < childArray.length(); y++) {
JSONObject obj = childArray.optJSONObject(y);
userSubMenuList.add(new UserSubMenu(obj.optString("code"),
obj.optString("title"), obj.optString("symbol_left"),
obj.optString("symbol_right")));
}
hashMapRight.put(headerListRight.get(headerListRight.size() - 1), userSubMenuList);
utils.printLog("AfterHashMap", "" + hashMapRight.size());
}
} catch (JSONException e) {
e.printStackTrace();
}
} else {
utils.showErrorDialog("Error Getting Data From Server");
utils.printLog("SuccessFalse", "Within getCategories");
}
} catch (JSONException e) {
e.printStackTrace();
utils.printLog("JSONObjEx_MainAct", responseStr);
}
} else {
utils.printLog("ResponseExMainActivity", responseStr);
throw new IllegalArgumentException("Activity cannot find extras " + KEY_EXTRA);
}
}
private void initLeftMenuData() {
headerListLeft = new ArrayList<>();
hashMapLeft = new HashMap<>();
String responseStr = "";
if (getIntent().hasExtra(KEY_EXTRA)) {
responseStr = getIntent().getStringExtra(KEY_EXTRA);
utils.printLog("ResponseInMainActivity", responseStr);
try {
JSONObject responseObject = new JSONObject(responseStr);
utils.printLog("JSON_Response", "" + responseObject);
boolean success = responseObject.optBoolean("success");
if (success) {
try {
JSONObject homeObject = responseObject.getJSONObject("home");
JSONArray menuCategories = homeObject.optJSONArray("categoryMenu");
utils.printLog("Categories", menuCategories.toString());
for (int i = 0; i < menuCategories.length(); i++) {
JSONObject menuCategoryObj = menuCategories.getJSONObject(i);
JSONArray menuSubCategoryArray = menuCategoryObj.optJSONArray(
"children");
List<MenuSubCategory> childMenuList = new ArrayList<>();
for (int j = 0; j < menuSubCategoryArray.length(); j++) {
JSONObject menuSubCategoryObj = menuSubCategoryArray.getJSONObject(j);
MenuSubCategory menuSubCategory = new MenuSubCategory(
menuSubCategoryObj.optString("child_id"),
menuSubCategoryObj.optString("name"));
childMenuList.add(menuSubCategory);
}
MenuCategory menuCategory = new MenuCategory(menuCategoryObj.optString(
"category_id"), menuCategoryObj.optString("name"),
menuCategoryObj.optString("icon"), childMenuList);
headerListLeft.add(menuCategory);
hashMapLeft.put(headerListLeft.get(i), menuCategory.getMenuSubCategory());
}
} catch (JSONException e) {
e.printStackTrace();
}
}
} catch (JSONException e) {
e.printStackTrace();
}
} else {
utils.printLog("ResponseExMainActivity", responseStr);
throw new IllegalArgumentException("Activity cannot find extras " + KEY_EXTRA);
}
}
private void actionbarToggle() {
mDrawerToggle = new ActionBarDrawerToggle(MainActivity.this, drawer,
R.string.navigation_drawer_open, R.string.navigation_drawer_close) {
public void onDrawerClosed(View view) {
super.onDrawerClosed(view);
drawerIconLeft.setImageResource(R.drawable.ic_list_black);
drawerIconLeft.setScaleX(-1);
}
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
}
};
}
#Override
public void onClick(View v) {
int id = v.getId();
if (id == R.id.logo_icon) {
recreate();
} else if (id == R.id.my_account_tv) {
utils.switchFragment(new Dashboard());
} else if (id == R.id.disc_tv) {
utils.printLog("From = Main Act");
Bundle bundle = new Bundle();
bundle.putString("from", "mainActivity");
utils.switchFragment(new FragProduct(), bundle);
} else if (id == R.id.checkout_tv) {
if (isLoggedIn()) {
utils.switchFragment(new FragCheckout());
} else {
AlertDialog alertDialog = utils.showAlertDialogReturnDialog("Continue As",
"Select the appropriate option");
alertDialog.setButton(DialogInterface.BUTTON_POSITIVE,
"As Guest", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
utils.switchFragment(new FragCheckout());
}
});
alertDialog.setButton(DialogInterface.BUTTON_NEGATIVE,
"Login", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
utils.switchFragment(new FragLogin());
}
});
alertDialog.setButton(DialogInterface.BUTTON_NEUTRAL,
"Register", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
utils.switchFragment(new FragRegister());
}
});
alertDialog.show();
}
} else if (id == R.id.home_tv) {
recreate();
} else if (id == R.id.search_icon) {
startActivityForResult(new Intent(context, SearchActivity.class), SEARCH_REQUEST_CODE);
} else if (id == R.id.cart_layout) {
Bundle bundle = new Bundle();
bundle.putString("midFix", "cartProducts");
utils.switchFragment(new FragCartDetail(), bundle);
}
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == SEARCH_REQUEST_CODE || requestCode == CURRENCY_REQUEST_CODE
|| requestCode == LANGUAGE_REQUEST_CODE) {
if (data != null) {
String responseStr = data.getStringExtra("result");
utils.printLog("ResponseIs = " + responseStr);
if (responseStr != null) {
if (resultCode == Activity.RESULT_OK) {
JSONObject response;
if (!isJSONString(responseStr)) {
try {
response = new JSONObject(responseStr);
if (requestCode == CURRENCY_REQUEST_CODE) {
JSONObject object = response.optJSONObject("currency");
Preferences.setSharedPreferenceString(appContext
, CURRENCY_SYMBOL_KEY
, object.optString("symbol_left")
+ object.optString("symbol_right")
);
recreate();
} else if (requestCode == LANGUAGE_REQUEST_CODE) {
JSONObject object = response.optJSONObject("language");
Preferences.setSharedPreferenceString(appContext
, LANGUAGE_KEY
, object.optString("code")
);
recreate();
}
} catch (JSONException e) {
e.printStackTrace();
}
} else {
if (requestCode == SEARCH_REQUEST_CODE) {
if (responseStr.isEmpty())
return;
Bundle bundle = new Bundle();
bundle.putString("id", responseStr);
bundle.putString("from", "fromSearch");
utils.switchFragment(new FragProduct(), bundle);
} else {
utils.showAlertDialog("Alert", responseStr);
}
}
} else if (resultCode == FORCED_CANCEL) {
utils.printLog("WithinSearchResult", "If Success False" + responseStr);
} else if (resultCode == Activity.RESULT_CANCELED) {
utils.printLog("WithinSearchResult", "Result Cancel" + responseStr);
}
}
}
}
}
}
MainFragment
public class MainFrag extends MyBaseFragment {
public MainFrag() {}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.frag_main, container, false);
initUtils();
initViews(view);
utils.setupSlider(mPager, indicator, pb, true, true);
RecyclerView.LayoutManager mLayoutManager =
new LinearLayoutManager(getActivity()
, LinearLayoutManager.VERTICAL, false);
mRecyclerView.setLayoutManager(mLayoutManager);
List<String> keysList = prepareData();
if (keysList.size() > 0 && !keysList.isEmpty()) {
mRecyclerView.setAdapter(new MainFragmentAdapter(keysList));
}
return view;
}
private void initViews(View view) {
mRecyclerView = view.findViewById(R.id.parent_recycler_view);
mPager = view.findViewById(R.id.pager);
indicator = view.findViewById(R.id.indicator);
pb = view.findViewById(R.id.loading);
}
private List<String> prepareData() {
String responseStr = getHomeExtra();
List<String> keysStr = new ArrayList<>();
try {
JSONObject responseObject = new JSONObject(responseStr);
utils.printLog("JSON_Response", "" + responseObject);
boolean success = responseObject.optBoolean("success");
if (success) {
JSONObject homeObject = responseObject.optJSONObject("home");
JSONObject modules = homeObject.optJSONObject("modules");
Iterator<?> keys = modules.keys();
while (keys.hasNext()) {
String key = (String) keys.next();
keysStr.add(key);
utils.printLog("KeyStr", key);
}
utils.printLog("ModuleSize", modules.toString());
} else {
utils.printLog("SuccessFalse", "Within getCategories");
}
} catch (JSONException e) {
e.printStackTrace();
utils.printLog("JSONEx_MainFragTest", responseStr);
}
return keysStr;
}
}
I removed global variables and some method because of length.
You should not use recreate() method here, as it forces the activity to reload everything. Just use intent to call your Home activity, that should solve this issue.
From the hint of #Akash Khatri I use to switch to mainFragment and its fine now. Actually #Akash is right recreate(); everything at present But as I was setting main fragment in OnCreate of MainActivity. So, It was hard to notice that Android first recreate everything and in no time It call the main Fragment.
I do not using Intent to start the same activity again Because Switching fragment is more convenient. And also I pass Some extras to it that I will loose With new Intent.
Related
I added my application to Github to find my bug.
So the bug is like when I open my app for a first time and open "info" then "settings" and click thought all options, then "new measurement" then it goes to previous screen (settings) instead of new measurement. Could anybody help me?
Here is the link to app
Edit:
Here are probably the meaningfull classes:
Stages.java
public class Stages extends BaseActivity {
private final Stage0StageFragment stageZeroFragment = new Stage0StageFragment();
private final Stage1StageFragment stageOneFragment = new Stage1StageFragment();
private final Stage2StageFragment stageTwoFragment = new Stage2StageFragment();
private final Stage3StageFragment stageThreeFragment = new Stage3StageFragment();
private BottomNavigationView bottomNavView;
private int startingPosition, newPosition;
OnSwitchFragmentFromStageTwo onSwitchFragmentFromStageTwo;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Util.setThemeBasedOnPrefs(this);
setContentView(R.layout.stages);
spEditor.putBoolean("wantToClosePxCmInfo", false).apply();
bottomNavView = findViewById(R.id.bottom_navigation);
bottomNavView.setItemIconTintList(null);
bottomNavView.setOnNavigationItemSelectedListener(item -> {
if (bottomNavView.getSelectedItemId() == R.id.navigation_stage_zero) {
if (!sp.getBoolean("correctionDone", false)) {
AlertDialog alertDialog = Util.createAlertDialog(Stages.this, android.R.drawable.ic_dialog_info, R.string.hide_dialog_title, getString(R.string.stage_zero_confirmation), (dialog, which) -> {
spEditor.putBoolean("correctionDone", true).apply();
bottomNavView.setSelectedItemId(item.getItemId());
showFragment(item.getItemId());
});
alertDialog.setOnShowListener(arg0 -> setAlertDialogButtonsAttributes(alertDialog));
alertDialog.show();
return false;
} else {
showFragment(item.getItemId());
return true;
}
} else if (bottomNavView.getSelectedItemId() == R.id.navigation_stage_two) {
try {
if (onSwitchFragmentFromStageTwo.onSwitchFragmentFromFragmentTwo() <= 0.5 && !sp.getBoolean("wantToClosePxCmInfo", false)) {
AlertDialog ad = Util.createAlertDialog(Stages.this, android.R.drawable.ic_dialog_alert, R.string.hide_dialog_title_alert,
getResources().getString(R.string.benchmark_not_drawn), (dialog, which) -> {
spEditor.putBoolean("wantToClosePxCmInfo", true).apply();
bottomNavView.setSelectedItemId(item.getItemId());
showFragment(item.getItemId());
});
ad.setOnShowListener(arg0 -> setAlertDialogButtonsAttributes(ad));
ad.show();
return false;
} else {
showFragment(item.getItemId());
return true;
}
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
} else {
showFragment(item.getItemId());
}
return true;
});
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
if (!sp.getBoolean("correctionDone", false))
ft.replace(R.id.content_frame, stageZeroFragment);
else {
ft.replace(R.id.content_frame, stageOneFragment);
bottomNavView.setSelectedItemId(R.id.navigation_stage_one);
}
ft.commit();
}
#Override
BaseActivity getActivity() {
return this;
}
private void setAlertDialogButtonsAttributes(AlertDialog alertDialog2) {
alertDialog2.getButton(DialogInterface.BUTTON_NEGATIVE).setBackground(AppCompatResources.getDrawable(this, R.drawable.button_selector));
alertDialog2.getButton(DialogInterface.BUTTON_POSITIVE).setBackground(AppCompatResources.getDrawable(this, R.drawable.button_selector));
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT,
1.0f
);
params.setMargins(10, 0, 10, 0);
alertDialog2.getButton(DialogInterface.BUTTON_NEGATIVE).setLayoutParams(params);
alertDialog2.getButton(DialogInterface.BUTTON_POSITIVE).setLayoutParams(params);
}
public void showFragment(int viewId) {
Fragment fragment = null;
switch (viewId) {
case R.id.navigation_stage_zero:
if (bottomNavView.getSelectedItemId() != R.id.navigation_stage_zero) {
fragment = stageZeroFragment;
newPosition = 0;
}
break;
case R.id.navigation_stage_one:
if (bottomNavView.getSelectedItemId() != R.id.navigation_stage_one) {
fragment = stageOneFragment;
newPosition = 1;
}
break;
case R.id.navigation_stage_two:
if (bottomNavView.getSelectedItemId() != R.id.navigation_stage_two) {
fragment = stageTwoFragment;
newPosition = 2;
}
break;
case R.id.navigation_stage_three:
if (bottomNavView.getSelectedItemId() != R.id.navigation_stage_three) {
fragment = stageThreeFragment;
newPosition = 3;
}
break;
}
if (fragment != null) {
if (startingPosition > newPosition) {
getSupportFragmentManager()
.beginTransaction()
.setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_right)
.replace(R.id.content_frame, fragment).commit();
}
if (startingPosition < newPosition) {
getSupportFragmentManager()
.beginTransaction()
.setCustomAnimations(R.anim.slide_in_right, R.anim.slide_out_left)
.replace(R.id.content_frame, fragment).commit();
}
startingPosition = newPosition;
}
}
}
Stage0StageFragment.java
public class Stage0StageFragment extends AbstractStageFragment {
private CheckBox checkboxSkip;
private int xCorrection, yCorrection;
private IndicatorSeekBar indicatorSeekBar;
private IndicatorSeekBar indicatorSeekBar2;
private AlertDialog alertDialog;
#Override
int getLayout() {
return R.layout.stage_zero;
}
#Override
public void onResume() {
super.onResume();
new CameraOpenerTask(this).execute();
}
#Override
public void onPause() {
super.onPause();
spEditor.putInt("indicator1", indicatorSeekBar.getProgress());
spEditor.putInt("indicator2", indicatorSeekBar2.getProgress());
spEditor.apply();
if (alertDialog.isShowing())
alertDialog.dismiss();
}
#Override
#SuppressLint({"ClickableViewAccessibility", "CommitPrefEdits"})
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
view.setOnTouchListener((v, event) -> {
int aktX = (int) event.getX();
int aktY = (int) event.getY();
setParamsToDrawRectangle(aktX, aktY);
return true;
});
configureSeekBars(view);
configureInitDialog();
}
#Override
public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
Imgproc.cvtColor(inputFrame.rgba(), mRgba, Imgproc.COLOR_RGBA2RGB, 1);
Core.transpose(mGray, mGray);
Core.flip(mGray, mGray, -1);
Imgproc.line(mRgba, p1, p2, Util.BLUE);
Imgproc.line(mRgba, p3, p4, Util.BLUE);
Imgproc.rectangle(mRgba, new Point(touchedYD, touchedXL), new Point(touchedYU, touchedXR), Util.WHITE, 2);
return mRgba;
}
private void setParamsToDrawRectangle(int aktX, int aktY) {
// poziomo
if (-aktX + camLayHeight + (xCorrection * 10) < (camLayHeight / 2)) {
touchedXR = -aktX + camLayHeight + (xCorrection * 10);
if (touchedXR < 0) touchedXR = 0;
} else {
touchedXL = -aktX + camLayHeight + (xCorrection * 10);
if (touchedXL > camLayHeight) touchedXL = camLayHeight;
}
// pionowo
if (aktY - (yCorrection * 10) < (camLayWidth / 2)) {
touchedYU = aktY - (yCorrection * 10);
if (touchedYU < 0) touchedYU = 0;
} else {
touchedYD = aktY - (yCorrection * 10);
if (touchedYD > camLayWidth) touchedYD = camLayWidth;
}
}
public void configureSeekBars(View view) {
indicatorSeekBar = view.findViewById(R.id.percent_indicator);
indicatorSeekBar.setOnSeekChangeListener(new MyOnSeekChangeListener("x"));
indicatorSeekBar2 = view.findViewById(R.id.percent_indicator2);
indicatorSeekBar2.setOnSeekChangeListener(new MyOnSeekChangeListener("y"));
TextView tv = view.findViewById(R.id.info_about_indicators);
if (sp.getInt("indicator1", 0) != 0)
indicatorSeekBar.setProgress(sp.getInt("indicator1", 0));
if (sp.getInt("indicator2", 0) != 0)
indicatorSeekBar2.setProgress(sp.getInt("indicator2", 0));
if (sp.getInt("indicator1", 0) != 0 || sp.getInt("indicator2", 0) != 0)
tv.setVisibility(View.VISIBLE);
}
public void setScrollViewParamsDependingOnFont(View checkboxLayout) {
ScrollView layout = checkboxLayout.findViewById(R.id.scrollView);
ViewGroup.LayoutParams params = layout.getLayoutParams();
String fontPref = sp.getString("font", "Arial");
if (fontPref.equals("Ginger"))
params.height = (int) getResources().getDimension(R.dimen.height_of_checkbox);
if (fontPref.equals("Arial")) params.height = ViewGroup.LayoutParams.WRAP_CONTENT;
layout.setLayoutParams(params);
}
void configureInitDialog() {
View checkboxLayout = View.inflate(getActivity(), R.layout.checkbox, null);
setScrollViewParamsDependingOnFont(checkboxLayout);
alertDialog = new AlertDialog.Builder(getActivity(), R.style.MyStyle).create();
alertDialog.setView(checkboxLayout);
alertDialog.setIcon(android.R.drawable.ic_dialog_info);
alertDialog.setTitle("Info");
alertDialog.setMessage(getResources().getString(R.string.stage_zero_dialog));
alertDialog.setCancelable(false);
alertDialog.setButton(DialogInterface.BUTTON_NEUTRAL, "Ok", (dialogInterface, i) -> {
String checkBoxResult = "";
checkboxSkip = checkboxLayout.findViewById(R.id.checkboxSkip);
if (checkboxSkip.isChecked())
checkBoxResult = "linia2";
if (checkBoxResult.equals("linia2"))
spEditor.putBoolean("hideDialog", true).apply();
});
alertDialog.setOnShowListener(arg0 -> alertDialog.getButton(DialogInterface.BUTTON_NEUTRAL).setBackground(ResourcesCompat.getDrawable(getResources(), R.drawable.button_selector, null)));
if (!sp.getBoolean("hideDialog", false))
alertDialog.show();
}
public class MyOnSeekChangeListener implements OnSeekChangeListener {
private final String axisCorrection;
MyOnSeekChangeListener(String axisCorrection) {
this.axisCorrection = axisCorrection;
}
#Override
public void onSeeking(SeekParams seekParams) {
if (axisCorrection.equals("x"))
xCorrection = seekParams.progress;
if (axisCorrection.equals("y"))
yCorrection = seekParams.progress;
spEditor.putInt("xCorrection", xCorrection);
spEditor.putInt("yCorrection", yCorrection);
spEditor.apply();
}
#Override
public void onStartTrackingTouch(IndicatorSeekBar indicatorSeekBar) {
}
#Override
public void onStopTrackingTouch(IndicatorSeekBar indicatorSeekBar) {
}
}
Something wrong happen in those classes probably when opening "new measurement".
I have a list of threads which I have paginated to use an endless scroll the issue I'm having (well my users) is an OutOfMemoryError: Failed to allocate a [x] byte allocation with [y] free bytes and [z] until OOM. the x, y and z attribute is different per user but the cause of the bug is always in the same place and it's when I refresh the posts. I'm completely out of my depth here as I have no idea how to optimise my code or make it so this doesn't happen. As it's the biggest crash on my app at the moment. I've posted my PostFragment below please see the refreshPosts(ArrayList<Posts> newObjects) method as this is where the crash is happening.
public class PostFragment extends Fragment implements View.OnClickListener {
private View mRootView;
private GridLayoutManager mLayoutManager;
private ThreadItem mThreads;
private PostItem mPost;
private PostAdapter mAdapter;
private PostResponse mData;
private EmoticonResponse mEmoticon;
private PostFeedDataFactory mDataFactory;
private EmoticonFeedDataFactory mEmoticonDataFactory;
private static PostFragment mCurrentFragment;
private int REQUEST_CODE;
//Flip
private boolean isFlipped = false;
private Animation flipAnimation;
#BindView(R.id.postsRecyclerView)
RecyclerView mRecyclerView;
#BindView(R.id.toolbarForPosts)
Toolbar mToolbar;
#BindView(R.id.threadText)
TextView mThreadText;
#BindView(R.id.flipText)
TextView mFlipTextView;
#BindView(R.id.shareText)
TextView mShareTextView;
#BindView(R.id.replyText)
TextView mReplyTextView;
#BindView(R.id.scrimColorView)
View mBackgroundView;
#BindView(R.id.fabMenu)
FloatingActionButton mFabMenu;
#BindView(R.id.flipFab)
FloatingActionButton mFlipFab;
#BindView(R.id.shareFab)
FloatingActionButton mShareFab;
#BindView(R.id.replyFab)
FloatingActionButton mReplyFab;
//Collapsing Toolbar
#BindView(R.id.postParentAppBarLayout)
AppBarLayout postAppBarLayout;
#BindView(R.id.postCollapseToolbar)
CollapsingToolbarLayout postCollapseToolbarLayout;
#BindView(R.id.mainImageContainer)
ViewGroup mainContainer;
//Back to top
#BindView(R.id.backToTopButton)
Button mBackToTop;
public static boolean isFromReply;
//FAB
private boolean mIsFabOpen = false;
private Animation fab_open, fab_close, rotate_forward, rotate_backward;
//Pagination
private int mCurrentPage = 1;
private ArrayList<Posts> postList = new ArrayList<>();
private boolean mIsLoading = false;
private boolean mIsLastPage = false;
public static PostFragment newInstance(#NonNull ThreadItem threadItem) {
Bundle args = new Bundle();
args.putParcelable("ThreadItem", Parcels.wrap(threadItem));
mCurrentFragment = new PostFragment();
mCurrentFragment.setArguments(args);
isFromReply = false;
return mCurrentFragment;
}
public static PostFragment newPostInstance(#NonNull PostItem postItem) {
Bundle args = new Bundle();
args.putParcelable("PostItemFromCompose", Parcels.wrap(postItem));
mCurrentFragment = new PostFragment();
mCurrentFragment.setArguments(args);
isFromReply = true;
return mCurrentFragment;
}
public PostFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mRootView = inflater.inflate(R.layout.fragment_post, container, false);
if (savedInstanceState == null) {
ButterKnife.bind(this, mRootView);
initUI();
}
return mRootView;
}
private void initUI() {
//UI Setup
mLayoutManager = new GridLayoutManager(getActivity(), 1);
mRecyclerView.setLayoutManager(mLayoutManager);
mDataFactory = new PostFeedDataFactory(getActivity());
mEmoticonDataFactory = new EmoticonFeedDataFactory(getActivity());
TextView textThreadTopic = (TextView) mRootView.findViewById(R.id.threadTopic);
TextView textNumPosts = (TextView) mRootView.findViewById(R.id.numPosts);
//FAB onClick Set-Up
mFabMenu.setOnClickListener(this);
mShareFab.setOnClickListener(this);
mReplyFab.setOnClickListener(this);
mFlipFab.setOnClickListener(this);
//FAB Animation Set up
fab_open = AnimationUtils.loadAnimation(getActivity().getApplicationContext(),
R.anim.fab_open);
fab_close = AnimationUtils.loadAnimation(getActivity().getApplicationContext(),
R.anim.fab_close);
rotate_forward = AnimationUtils.loadAnimation(getActivity().getApplicationContext(),
R.anim.rotate_forward);
rotate_backward = AnimationUtils.loadAnimation(getActivity().getApplicationContext(),
R.anim.rotate_backward);
//Toolbar
((AppCompatActivity) getActivity()).setSupportActionBar(mToolbar);
((AppCompatActivity) getActivity()).getSupportActionBar().setDisplayShowTitleEnabled(false);
mToolbar.setNavigationIcon(R.drawable.ic_back_white);
mToolbar.invalidate();
mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getActivity().finish();
}
});
//Load Parcel
Intent intent = getActivity().getIntent();
mThreads = Parcels.unwrap(getArguments().getParcelable("ThreadItem"));
mPost = Parcels.unwrap(getArguments().getParcelable("PostItemFromCompose"));
if (mThreads != null) {
if (mThreads.getName() != null) {
mThreadText.setText(mThreads.getName());
}
if (mThreads.getTopic_name() != null) {
textThreadTopic.setText(mThreads.getTopic_name());
}
if (mThreads.getNum_posts() != null) {
int numPosts = Integer.parseInt(mThreads.getNum_posts());
if (numPosts > 1000) {
textNumPosts.setText("1K");
} else {
textNumPosts.setText(mThreads.getNum_posts());
}
}
}
postAppBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
boolean isShow = false;
int scrollRange = -1;
#Override
public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
if (scrollRange == -1) {
scrollRange = appBarLayout.getTotalScrollRange();
}
if (scrollRange + verticalOffset == 0) {
postCollapseToolbarLayout.setTitle("Threads");
mainContainer.setVisibility(View.INVISIBLE);
isShow = true;
} else if (isShow) {
postCollapseToolbarLayout.setTitle("");
isShow = false;
mainContainer.setVisibility(View.VISIBLE);
}
}
});
flipAnimation =
AnimationUtils.loadAnimation(getActivity().getApplicationContext(), R.anim.flip);
loadData(true, 1);
}
private void loadData(final boolean firstLoad, int readDirection) {
if (isFromReply) {
if (mPost.getThread_id() != null) {
mDataFactory.getPostFeed(mPost.getThread_id(), readDirection, mCurrentPage,
new PostFeedDataFactory.PostFeedDataFactoryCallback() {
#Override
public void onPostDataReceived(PostResponse response) {
mData = response;
if (mData.getItems() != null) {
for (int i = 0; i < mData.getItems().size(); i++) {
Posts singlePost = response.getItems().get(i);
postList.add(singlePost);
}
if (firstLoad) {
mIsLoading = false;
mData.getItems().clear();
mData.getItems().addAll(postList);
mEmoticonDataFactory.getEmoticonFeed(
new EmoticonFeedDataFactory.EmoticonFeedDataFactoryCallback() {
#Override
public void onEmoticonDataReceived(EmoticonResponse response) {
mEmoticon = response;
populateUIWithData();
}
#Override
public void onEmoticonDataFailed(Exception exception) {
}
});
} else {
mIsLoading = false;
refreshPosts(postList);
}
if (mData.getItems().size() > 0) {
if (Integer.valueOf(mData.getTotalPosts()) >= response.getItems().size()) {
mCurrentPage++;
} else {
mIsLastPage = true;
}
}
}
}
#Override
public void onPostDataFailed(Exception exception) {
customToast("Error: " + exception.toString());
}
});
}
} else {
if (mThreads.getId() != null)
mDataFactory.getPostFeed(mThreads.getId(), readDirection, mCurrentPage,
new PostFeedDataFactory.PostFeedDataFactoryCallback() {
#Override
public void onPostDataReceived(PostResponse response) {
mData = response;
if (mData.getItems() != null) {
for (int i = 0; i < mData.getItems().size(); i++) {
Posts singlePost = response.getItems().get(i);
postList.add(singlePost);
}
if (firstLoad) {
mIsLoading = false;
mData.getItems().clear();
mData.getItems().addAll(postList);
mEmoticonDataFactory.getEmoticonFeed(
new EmoticonFeedDataFactory.EmoticonFeedDataFactoryCallback() {
#Override
public void onEmoticonDataReceived(EmoticonResponse response) {
mEmoticon = response;
populateUIWithData();
}
#Override
public void onEmoticonDataFailed(Exception exception) {
}
});
} else {
mIsLoading = false;
refreshPosts(postList);
}
if (mData.getItems().size() > 0) {
if (Integer.valueOf(mData.getTotalPosts()) >= response.getItems().size()) {
mCurrentPage++;
} else {
mIsLastPage = true;
}
}
}
}
#Override
public void onPostDataFailed(Exception exception) {
customToast("Error: " + exception.toString());
}
});
}
}
private void populateUIWithData() {
ImageButton moreOptionsButton = (ImageButton) mRootView.findViewById(R.id.moreOptions);
moreOptionsButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
PopupMenu popupMenu = new PopupMenu(v.getContext(), v);
popupMenu.inflate(R.menu.thread_options);
popupMenu.getMenu();
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.watch:
WatchedThreadsRequestData watchedThreadsRequestData = new WatchedThreadsRequestData(getActivity());
watchedThreadsRequestData.setWatchedThread(mThreads.getId(), new WatchedThreadsRequestData.WatchedThreadsFeedback() {
#Override
public void onWatchedRequestReceived(ThreadResponse response) {
customToast("Thread watched");
}
#Override
public void onWatchedRequestFailed(Exception exception) {
customToast("Thread wasn't watched: " + exception.toString());
}
});
return true;
case R.id.shareThread:
Intent sharingIntent = new Intent(Intent.ACTION_SEND);
sharingIntent.putExtra(Intent.EXTRA_TEXT, mThreads.getName() + " - " + Constants.LIVE_URL +
"talk/" + mThreads.getTopic_url() + '/' + mThreads.getThread_url());
sharingIntent.setType("text/plain");
getActivity().startActivity(Intent.createChooser(sharingIntent, "Share via"));
return true;
case R.id.hideThread:
customToast("Hide: coming soon");
return true;
default:
customToast("Somethings Wrong");
return true;
}
}
});
setForceShowIcon(popupMenu);
popupMenu.show();
}
});
if (mAdapter == null) {
mAdapter = new PostAdapter(getActivity(), mData, mEmoticon);
mRecyclerView.setAdapter(mAdapter);
} else {
mAdapter.setData(mData.getItems());
mAdapter.notifyDataSetChanged();
}
mRecyclerView.addOnScrollListener(paginationListener);
}
public static void setForceShowIcon(PopupMenu popupMenu) {
try {
Field[] fields = popupMenu.getClass().getDeclaredFields();
for (Field field : fields) {
if ("mPopup".equals(field.getName())) {
field.setAccessible(true);
Object menuPopupHelper = field.get(popupMenu);
Class<?> classPopupHelper = Class.forName(menuPopupHelper
.getClass().getName());
Method setForceIcons = classPopupHelper.getMethod(
"setForceShowIcon", boolean.class);
setForceIcons.invoke(menuPopupHelper, true);
break;
}
}
} catch (Throwable e) {
e.printStackTrace();
}
}
private RecyclerView.OnScrollListener paginationListener = new RecyclerView.OnScrollListener() {
#Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
boolean hasEnded = newState == SCROLL_STATE_IDLE;
if (hasEnded) {
mFabMenu.show();
mFabMenu.setClickable(true);
} else {
if (mIsFabOpen)
closeMenu();
mFabMenu.hide();
mFabMenu.setClickable(false);
}
}
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
int visibleItemCount = mLayoutManager.getChildCount();
int totalItemCount = mLayoutManager.getItemCount();
int firstVisibleItemPosition = mLayoutManager.findFirstVisibleItemPosition();
if (!mIsLoading && !mIsLastPage) {
if ((visibleItemCount + firstVisibleItemPosition) >= totalItemCount) {
loadMoreItems();
}
}
//Back to top
if (mLayoutManager.findLastVisibleItemPosition() == totalItemCount - 1) {
mBackToTop.setVisibility(View.VISIBLE);
mBackToTop.setClickable(true);
mBackToTop.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mLayoutManager.scrollToPositionWithOffset(0,0);
}
});
} else {
mBackToTop.setVisibility(View.GONE);
mBackToTop.setClickable(false);
}
}
};
private void loadMoreItems() {
if (!isFlipped) {
mIsLoading = true;
loadData(false, 1);
} else {
mIsLoading = true;
loadData(false, -1);
}
}
private void refreshPosts(ArrayList<Posts> newObjects) {
postList.addAll(newObjects);
populateUIWithData();
}
#Override
public void onClick(View v) {
int id = v.getId();
switch (id) {
case R.id.fabMenu:
animateFAB();
break;
case R.id.shareFab:
share();
break;
case R.id.replyFab:
reply();
break;
case R.id.flipFab:
flip();
break;
}
}
public void animateFAB() {
if (mIsFabOpen) {
closeMenu();
} else {
mFabMenu.startAnimation(rotate_forward);
mReplyFab.startAnimation(fab_open);
mShareFab.startAnimation(fab_open);
mFlipFab.startAnimation(fab_open);
mReplyFab.setClickable(true);
mShareFab.setClickable(true);
mFlipFab.setClickable(true);
mFlipTextView.setVisibility(View.VISIBLE);
mShareTextView.setVisibility(View.VISIBLE);
mReplyTextView.setVisibility(View.VISIBLE);
mBackgroundView.setVisibility(View.VISIBLE);
mIsFabOpen = true;
}
}
private void closeMenu() {
mFabMenu.startAnimation(rotate_backward);
mReplyFab.startAnimation(fab_close);
mShareFab.startAnimation(fab_close);
mFlipFab.startAnimation(fab_close);
mReplyFab.setClickable(false);
mShareFab.setClickable(false);
mFlipFab.setClickable(false);
mFlipTextView.setVisibility(View.INVISIBLE);
mShareTextView.setVisibility(View.INVISIBLE);
mReplyTextView.setVisibility(View.INVISIBLE);
mBackgroundView.setVisibility(View.INVISIBLE);
mIsFabOpen = false;
}
private void reply() {
PreferenceConnector.writeString(getActivity().getApplicationContext(), "threadID", mThreads.getId());
PreferenceConnector.writeString(getActivity().getApplicationContext(), "threadTitle", mThreads.getName());
if (PreferenceConnector.readString(getActivity(), "authToken") == null ||
PreferenceConnector.readString(getActivity(), "authToken").equalsIgnoreCase("skip")) {
final AlertDialog.Builder loginDialog = new AlertDialog.Builder(getActivity());
loginDialog.setTitle("Please log in");
loginDialog.setMessage("You need to be logged in to reply");
loginDialog.setPositiveButton("Log in", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(getActivity().getApplicationContext(), LoginActivity.class);
startActivity(intent);
}
});
loginDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
loginDialog.show();
} else {
closeMenu();
Intent intent = new Intent(getActivity().getApplicationContext(), NewPostActivity.class);
intent.putExtra("Threads", Parcels.wrap(mThreads));
getActivity().finish();
startActivityForResult(intent, REQUEST_CODE);
}
}
private void share() {
Intent sharingIntent = new Intent(Intent.ACTION_SEND);
sharingIntent.putExtra(Intent.EXTRA_TEXT, mThreads.getName() + " - " + Constants.LIVE_URL +
"talk/" + mThreads.getTopic_url() + '/' + mThreads.getThread_url());
sharingIntent.setType("text/plain");
startActivity(Intent.createChooser(sharingIntent, "Share via"));
}
private void flip() {
if (!isFlipped) {
mAdapter.clearAll();
isFlipped = true;
mRecyclerView.startAnimation(flipAnimation);
loadData(false, -1);
closeMenu();
} else {
mAdapter.clearAll();
isFlipped = false;
mRecyclerView.startAnimation(flipAnimation);
loadData(true, 1);
closeMenu();
}
}
private void customToast(String toastMessage) {
LayoutInflater inflater = getActivity().getLayoutInflater();
View layout = inflater.inflate(R.layout.custom_toast,
(ViewGroup) getActivity().findViewById(R.id.toastContainer));
TextView customToastText = (TextView) layout.findViewById(R.id.customToastText);
customToastText.setText(toastMessage);
Toast toast = new Toast(getActivity().getApplicationContext());
toast.setGravity(Gravity.BOTTOM, 0, 25);
toast.setDuration(Toast.LENGTH_LONG);
toast.setView(layout);
toast.show();
}
#Override
public void onResume() {
super.onResume();
if (mData != null && mAdapter != null) {
mAdapter.notifyDataSetChanged();
}
getView().setFocusableInTouchMode(true);
getView().requestFocus();
getView().setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK) {
if (mIsFabOpen) {
closeMenu();
} else {
getActivity().finish();
}
return true;
}
return false;
}
});
}
public void updateView() {
mAdapter.notifyDataSetChanged();
}
}
Thanks in advance once again.
Your problem basically boils down to this:
private void refreshPosts(ArrayList<Posts> newObjects) {
postList.addAll(newObjects);
populateUIWithData();
}
The list can only get bigger, never smaller. If the server has lots and lots of posts, then OutOfMemory is pretty much inevitable.
One approach to solving this problem is to use an LRU (Least Recently Used) cache. There is a utility class you can use: android.util.LruCache.
An LRU Cache is essentially a Map. Items are stored with a key, like an ID. With an LRU cache, you put new items in, but once a pre-determined limit is reached, old items start getting pushed out to make room for new items.
This will save memory, but make a lot more management code for you.
Your adapter, instead of having a list of posts, will just have a list of the post IDs. This should be much easier on memory.
As the user scrolls and you collect more posts, you add the post ID to the list, and map the post into the LRU cache using the post ID.
When you bind to the list item view, you look up the post using the post's ID in the LRU cache.
If it's there, great. That's called a cache hit. Bind the post to the
list item view.
If not, then you have a cache miss. You have some work to do.
Start a server request to retrieve the post by ID. I see your current code just retrieves blocks of posts, so you'll need some new server code here.
When the request completes, put the post in the LRU cache and let the adapter know your item has changed using adapter.notifyItemChanged(). Unless the user has scrolled beyond it, the RecyclerView should try to bind with the list item view again. This time, you should get a cache hit.
This is the basic idea. I'd write some code, but I still have a lot of questions since I can't see your model classes, data factories, and adapter class.
Once you have it working, you have to tune the limit on the cache so that it's low enough not to overrun memory, but high enough that your hit/miss ratio isn't close to zero.
BTW, I noticed that you are making the mistake of creating a new adapter and handing it to the RecyclerView each time you get a block of posts. You should create your adapter once, keep a reference to it and update it. Have a method that adds a block of posts then calls notifyDataSetChanged().
Another idea for conserving memory is to use text compression. If the problem is more a result of a large average size of the post rather than a large number of posts, you might explore this idea in addition to the LRU cache.
The concept is that you could take posts over a certain size, write them into a buffer using a ZipOutputStream then save the buffer in memory. When it's time to display the post, you read the buffer with a ZipInputStream to uncompress the text. Here the issue is performance as the compression/decompression is pretty CPU-intensive. But if the problem is really long posts, this approach might be something to consider.
An even better approach: Only save the first part of the post as an "overview" display in the list. When the user clicks on the list item, retrieve the entire post from the server and display that in another page.
i have an activity with recyclerview that extends fragment activity.
When an item is clicked from a recyerview, i want to get the title and display it as a pop up message.
i tried several ways but noting works. cam some one help me to do this TNX.
PickupActivity
public class PickupActivity extends AppCompatActivity implements View.OnClickListener{
private Toolbar toolbar;
private navigationDrawerFragment drawerFragment;
ApplicationEnvironmentURL applicationEnvironment;
ProgressDialog pDialog;
Context context;
String BASEURL;
String FilteredData;
String AllAgents;
public String ProfileId;
public String companyId;
public String profileToken;
private com.github.clans.fab.FloatingActionButton pik_fab1;
private com.github.clans.fab.FloatingActionButton pik_fab2;
private com.github.clans.fab.FloatingActionButton pik_fab3;
private com.github.clans.fab.FloatingActionButton pik_fab4;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setTitle("Dashboard");
setContentView(R.layout.activity_pickup);
applicationEnvironment = new ApplicationEnvironmentURL(this.context);
context = this.getApplicationContext();
toolbar = (Toolbar) findViewById(R.id.app_bar_dashboard);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayShowHomeEnabled(true);
drawerFragment = (navigationDrawerFragment)
getSupportFragmentManager().findFragmentById(R.id.fragment_navigation_drawer);
drawerFragment.setup(R.id.fragment_navigation_drawer, (DrawerLayout) findViewById(R.id.drawer_layout), toolbar);
pik_fab1 = (com.github.clans.fab.FloatingActionButton) findViewById(R.id.pickup_delete);
pik_fab2 = (com.github.clans.fab.FloatingActionButton) findViewById(R.id.pickup_close);
pik_fab3 = (com.github.clans.fab.FloatingActionButton) findViewById(R.id.pickup_assignto);
pik_fab4 = (com.github.clans.fab.FloatingActionButton) findViewById(R.id.pickup_pickup);
pik_fab1.setOnClickListener(this);
pik_fab2.setOnClickListener(this);
pik_fab3.setOnClickListener(this);
pik_fab4.setOnClickListener(this);
SharedPreferences prefs = getSharedPreferences("zupportdesk", MODE_PRIVATE);
String islogged = prefs.getString("islogged", "Not defined");
String userid = prefs.getString("userid", "Not defined");
profileToken = prefs.getString("profileToken", "Not defined");
companyId = prefs.getString("companyId", "Not defined");
String companyName = prefs.getString("companyName", "Not defined");
ProfileId = prefs.getString("ProfileId", "Not defined");
Log.d("islogged : ", islogged);
Log.d("userid : ", userid);
Log.d("profileToken : ", profileToken);
Log.d("companyId : ", companyId);
Log.d("companyName : ", companyName);
Log.d("ProfileId : ", ProfileId);
getTickets(ProfileId, companyId, profileToken);
View newTicket = findViewById(R.id.newtic);
newTicket.setOnClickListener(onClickListener);
}
#Override
public void onClick(View v) {
int id = v.getId();
switch (id) {
case R.id.pickup_pickup:
Log.d("Fab_clicked", "Pickup Ticket");
pickupTicketMessage("Are you sure you want to pickup the selected tickets?", "Confirm?");
break;
case R.id.pickup_close:
Log.d("Fab_clicked", "close tickets");
closeTicketMessage("Are you sure you want to close the selected tickets?", "Confirm?");
break;
case R.id.pickup_delete:
Log.d("Fab_clicked", "close tickets");
DeleteTicketMessage("Are you sure you want to delete the selected tickets?", "Confirm?");
break;
case R.id.pickup_assignto:
Log.d("Fab_clicked", "Assign to Agent");
try {
assignTicketstMessage("Select an agent");
} catch (JSONException e) {
e.printStackTrace();
}
break;
}
}
/* Multiple Button on click event handle */
private View.OnClickListener onClickListener = new View.OnClickListener() {
#Override
public void onClick(final View v) {
switch(v.getId()){
case R.id.newtic:
// Create a login URl, before starting anything
if(isNetworkAvailable()){
Intent intentTicket = new Intent(PickupActivity.this, NewTicket.class);
startActivity(intentTicket);
} else {showErrorMessage("Please check your internet connection.", "No Connectivity!"); }
break;
}
}
};
public void getTickets(String profileId, String companyId, String profileToken) {
if (isNetworkAvailable()) {
try {
setFilteredDataURL(companyId, profileId);
FilteredData = new getFilteredData().execute(profileToken).get();
// adding the filtered data to shared preferences for further use.
//adding user data to shared preferences.
SharedPreferences.Editor editor = getSharedPreferences("zupportdesk", MODE_PRIVATE).edit();
editor.putString("FilteredData", FilteredData);
editor.commit();
Log.d("ZF-Filtered_Data", FilteredData);
setTicketsURL(profileId, companyId);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
new getNewTickets().execute(profileToken);
} else {
showErrorMessage("Please check your internet connection.", "No Connectivity!");
}
}
private void PickupTicket() throws JSONException {
JSONObject jsonObject = new JSONObject();
JSONArray TicketsArray = new JSONArray();
List<Integer> selected_item = new ArrayList<>();
for (PickupTicketsItemObject ticket : PickupActivityFragment.support_ticket) {
if (ticket.isSelected()) {
selected_item.add(Integer.valueOf(ticket.getTicket_id()));
TicketsArray.put(Integer.valueOf(ticket.getTicket_id()));
}
}
Log.d("pickup_ticket_size", String.valueOf(selected_item.size()));
if(selected_item.size() < 1){
Log.d("pickup_ticket_size", "empty");
//Show Error Message
}else {
Log.d("pickup_ticket_size", "have tickets");
jsonObject.put("TicketID", TicketsArray);
jsonObject.put("ProfileId", ProfileId);
jsonObject.put("CompanyID", companyId);
setPickupTicketURI();
Log.d("ZF-PickupTicket", String.valueOf(jsonObject));
new TicketPickupRequest().execute(String.valueOf(jsonObject), profileToken);
}
}
private void showSuccessMessage(String data, String title){
new AlertDialog.Builder(this)
.setTitle(title)
.setMessage(data)
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// restart Activity
finish();
startActivity(getIntent());
}
})
.setIcon(R.drawable.notification_success)
.show();
}
private void assignTicketstMessage(String title) throws JSONException {
AlertDialog.Builder b = new AlertDialog.Builder(this);
b.setTitle(title);
final List<String> agentList = new ArrayList<String>();
final List<String> agentProfileIDList = new ArrayList<String>();
if(AllAgents != null && !AllAgents.isEmpty() && !AllAgents.equals("null")) {
JSONArray jsonarray = new JSONArray(AllAgents);
int count = jsonarray.length();
Log.d("Full Agents", String.valueOf(count));
for (int k = 0; k < jsonarray.length(); k++) {
JSONObject jsonobject5 = jsonarray.getJSONObject(k);
Log.d("Agent object ", String.valueOf(jsonobject5));
agentList.add(jsonobject5.getString("FirstName"));
agentProfileIDList.add(jsonobject5.getString("ProfileId"));
}
String[] types = new String[agentList.size()];
for (int j = 0; j < agentList.size(); j++) {
types[j] = agentList.get(j);
}
b.setItems(types, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Log.d("Selected_no ", String.valueOf(which));
Log.d("Selected_agent ", String.valueOf(agentList.get(which)));
Log.d("Selected_profile_id ", String.valueOf(agentProfileIDList.get(which)));
dialog.dismiss();
assignTicketstMessage2(String.valueOf(agentList.get(which)), String.valueOf(agentProfileIDList.get(which)));
}
});
b.show();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
Intent i = new Intent(getApplicationContext(),Settings.class);
startActivity(i);
return true;
}
if(id == R.id.home){
NavUtils.navigateUpFromSameTask(this);
}
//noinspection SimplifiableIfStatement
if (id == R.id.notification){
Intent i = new Intent(getApplicationContext(), Notifications.class);
startActivity(i);
return true;
}
return super.onOptionsItemSelected(item);
}
private boolean isNetworkAvailable() {
ConnectivityManager connectivityManager
= (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}
private void showErrorMessage(String data, String title) {
new AlertDialog.Builder(this.context)
.setTitle(title)
.setMessage(data)
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
}
})
.setIcon(R.drawable.notification_red)
.show();
}
private void showErrorMessageNoInbox(String data, String title) {
new AlertDialog.Builder(this.context)
.setTitle(title)
.setMessage(data)
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// continue with delete
Intent i = new Intent(getApplicationContext(), Login.class);
startActivity(i);
}
})
.setIcon(R.drawable.notification_red)
.show();
}
public HttpClient getNewHttpClient() {
try {
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(null, null);
MySSLSocketFactory sf = new MySSLSocketFactory(trustStore);
sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
HttpParams params = new BasicHttpParams();
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
registry.register(new Scheme("https", sf, 443));
ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);
return new DefaultHttpClient(ccm, params);
} catch (Exception e) {
return new DefaultHttpClient();
}
}
......................... More
PickupActivityFragment
public class PickupActivityFragment extends Fragment {
public static ArrayList<PickupTicketsItemObject> support_ticket;
public static RecyclerView Ticketslist;
PickupActivity pick_up_activity;
public PickupActivityFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.activity_pickup_fragment, container, false);
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
pick_up_activity = new PickupActivity();
Ticketslist = (RecyclerView) view.findViewById(R.id.pickup_list);
Ticketslist.setLayoutManager(new LinearLayoutManager(getActivity()));
Ticketslist.setHasFixedSize(true);
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
pick_up_activity = new PickupActivity();
}
}
PickupTicketsAdapter
public class PickupTicketsAdapter extends RecyclerView.Adapter<PickupTicketsAdapter.ViewHolder> {
ArrayList<PickupTicketsItemObject> all_tickets;
public PickupTicketsAdapter(List<PickupTicketsItemObject> tickets) {
this.all_tickets = new ArrayList<>(tickets);
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.custom_pick_tickets, parent, false);
return new ViewHolder(v);
}
#Override
public void onBindViewHolder(final ViewHolder holder, int position) {
holder.bindData(all_tickets.get(position));
//in some cases, it will prevent unwanted situations
holder.checkbox.setOnCheckedChangeListener(null);
//if true, your checkbox will be selected, else unselected
holder.checkbox.setChecked(all_tickets.get(position).isSelected());
holder.checkbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
all_tickets.get(holder.getAdapterPosition()).setSelected(isChecked);
}
});
}
#Override
public int getItemCount() {
return all_tickets.size();
}
// Provide a reference to the views for each data item
// Complex data items may need more than one view per item, and
// you provide access to all the views for a data item in a view holder
public static class ViewHolder extends RecyclerView.ViewHolder {
// each data item is just a string in this case
public ImageView priority;
public TextView sts_open;
public TextView sts_overdue;
public TextView tkt_from;
public TextView tkt_subject;
public TextView tkt_assignedto;
public TextView tkt_created_date;
public TextView txt_ticket_id;
public CheckBox checkbox;
public ViewHolder(View v) {
super(v);
checkbox = (CheckBox) v.findViewById(R.id.pick_checkbox);
priority = (ImageView) v.findViewById(R.id.priority_status_icon);
sts_open= (TextView) v.findViewById(R.id.tv_Tk_opn_status);
sts_overdue = (TextView) v.findViewById(R.id.tv_Tk_overdue);
tkt_from = (TextView) v.findViewById(R.id.tv_Tk_from);
tkt_subject = (TextView) v.findViewById(R.id.tv_Tk_subject);
tkt_assignedto = (TextView) v.findViewById(R.id.tv_Tk_Assignedto);
tkt_created_date = (TextView) v.findViewById(R.id.tv_Tk_Created_date);
txt_ticket_id = (TextView) v.findViewById(R.id.tv_Tk_TicketID);
}
public void bindData(PickupTicketsItemObject ticket) {
priority.setImageResource(ticket.getStatus_priority());
sts_open.setText(ticket.getStatus_open());
sts_overdue.setText(ticket.getStatus_overdue());
tkt_from.setText(ticket.getTicket_from());
tkt_subject.setText(ticket.getTicket_subject());
tkt_assignedto.setText(ticket.getTicket_assignedto());
tkt_created_date.setText(ticket.getTicket_created_date());
txt_ticket_id.setText(ticket.getTicket_id());
}
}
}
PickupTicketsItemObject
public class PickupTicketsItemObject {
private int status_priority;
private String status_open;
private String status_overdue;
private String ticket_from;
private String ticket_subject;
private String ticket_assignedto;
private String ticket_created_date;
private String ticket_id;
private boolean isSelected;
public PickupTicketsItemObject(){
}
public int getStatus_priority() {
return status_priority;
}
public String getStatus_open() {
return status_open;
}
public String getStatus_overdue() {
return status_overdue;
}
public String getTicket_from() {
return ticket_from;
}
public String getTicket_subject() {
return ticket_subject;
}
public String getTicket_assignedto() {
return ticket_assignedto;
}
public String getTicket_created_date(){return ticket_created_date;}
public String getTicket_id(){return ticket_id;}
public boolean isSelected() {
return isSelected;
}
public void setSelected(boolean selected) {
isSelected = selected;
}
public void setStatus_priority(int status_priority) {
this.status_priority = status_priority;
}
public void setStatus_open(String status_open) {
this.status_open = status_open;
}
public void setStatus_overdue(String status_overdue) {
this.status_overdue = status_overdue;
}
public void setTicket_from(String ticket_from) {
this.ticket_from = ticket_from;
}
public void setTicket_subject(String ticket_subject) {
this.ticket_subject = ticket_subject;
}
public void setTicket_assignedto(String ticket_assignedto) {
this.ticket_assignedto = ticket_assignedto;
}
public void setTicket_created_date(String ticket_created_date) {
this.ticket_created_date = ticket_created_date;
}
public void setTicket_id(String ticket_id) {
this.ticket_id = ticket_id;
}
}
public void onBindViewHolder(.....)
for particular TextView and use AlertDialog to show message inside adapter.
All you need to do is make changes in your adapter class
In your ViewHolder class, declare a CardView object as well.
Then in the onBindViewHolder method you can set the holder.cardview.onClickListener
You can use alert dialog builder for showing popups
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 6 years ago.
public class MainActivity extends Activity {
private static final String TAG = "MainActivity";
ProductDatabase.ProductDatabaseHelper controller = new ProductDatabase.ProductDatabaseHelper(this);
EditText mBarcodeEdit;
EditText mFormatEdit;
EditText mTitleEdit;
EditText mPriceEdit;
private static final int ZBAR_SCANNER_REQUEST = 0;
private static final int ZBAR_QR_SCANNER_REQUEST = 1;
private static final ProductData mProductData = new ProductData();
Button mScanButton;
Button mAddButton;
Button mSelectButton;
Button mExportButton;
Button btnimport;
ProductDatabase mProductDb;
ListView ls;
TextView infotext;
File file = null;
// DatabaseHelper dbhelper = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ls = (ListView) findViewById(R.id.placeslist);
mBarcodeEdit = (EditText) findViewById(R.id.barcodeEdit);
mFormatEdit = (EditText) findViewById(R.id.codeFormatEdit);
mTitleEdit = (EditText) findViewById(R.id.titleEdit);
mPriceEdit = (EditText) findViewById(R.id.priceEdit);
mScanButton = (Button) findViewById(R.id.scan_btn);
mAddButton = (Button) findViewById(R.id.addButton);
mSelectButton = (Button) findViewById(R.id.selelctButton);
mProductDb = new ProductDatabase(this); // not yet shown
infotext = (TextView) findViewById(R.id.txtresulttext);
mExportButton = (Button) findViewById(R.id.exportbtn);
mSelectButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(MainActivity.this, product_list.class);
startActivity(i);
}
});
mAddButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String barcode = mBarcodeEdit.getText().toString();
String format = mFormatEdit.getText().toString();
String title = mTitleEdit.getText().toString();
String price = mPriceEdit.getText().toString();
String errors = validateFields(barcode, format, title, price);
if (errors.length() > 0) {
showInfoDialog(MainActivity.this, "Please fix errors", errors);
} else {
mProductData.barcode = barcode;
mProductData.format = format;
mProductData.title = title;
mProductData.price = new BigDecimal(price);
mProductDb.insert(mProductData);
showInfoDialog(MainActivity.this, "Success", "Product saved successfully");
resetForm();
}
}
});
mExportButton.setOnClickListener(new View.OnClickListener() {
SQLiteDatabase sqldb = controller.getReadableDatabase(); //My Database class
Cursor c =null;
#Override
public void onClick(View view) { //main code begins here
try {
c = sqldb.rawQuery("select * from spot_pay.db", null);
int rowcount = 0;
int colcount = 0;
File sdCardDir = Environment.getExternalStorageDirectory();
String filename = "MyBackUp.csv";
// the name of the file to export with
File saveFile = new File(sdCardDir, filename);
FileWriter fw = new FileWriter(saveFile);
BufferedWriter bw = new BufferedWriter(fw);
rowcount = c.getCount();
colcount = c.getColumnCount();
if (rowcount > 0) {
c.moveToFirst();
for (int i = 0; i < colcount; i++) {
if (i != colcount - 1) {
bw.write(c.getColumnName(i) + ",");
} else {
bw.write(c.getColumnName(i));
}
}
bw.newLine();
for (int i = 0; i < rowcount; i++) {
c.moveToPosition(i);
for (int j = 0; j < colcount; j++) {
if (j != colcount - 1)
bw.write(c.getString(j) + ",");
else
bw.write(c.getString(j));
}
bw.newLine();
}
bw.flush();
infotext.setText("Exported Successfully.");
}
} catch (Exception ex) {
if (sqldb.isOpen()) {
sqldb.close();
infotext.setText(ex.getMessage().toString());
}
} finally {
}
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu, menu);
return true;
}
private void showInfoDialog(Context context, String title, String information) {
new AlertDialog.Builder(context)
.setMessage(information)
.setTitle(title)
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
}).show();
}
private void resetForm() {
// TODO Auto-generated method stub
mBarcodeEdit.getText().clear();
mFormatEdit.getText().clear();
mTitleEdit.getText().clear();
mPriceEdit.getText().clear();
}
public void launchScanner(View v) {
if (isCameraAvailable()) {
Intent intent = new Intent(this, ZBarScannerActivity.class);
startActivityForResult(intent, ZBAR_SCANNER_REQUEST);
} else {
Toast.makeText(this, "Rear Facing Camera Unavailable", Toast.LENGTH_SHORT).show();
}
}
public void launchQRScanner(View v) {
if (isCameraAvailable()) {
Intent intent = new Intent(this, ZBarScannerActivity.class);
intent.putExtra(ZBarConstants.SCAN_MODES, new int[]{Symbol.QRCODE});
startActivityForResult(intent, ZBAR_SCANNER_REQUEST);
} else {
Toast.makeText(this, "Rear Facing Camera Unavailable", Toast.LENGTH_SHORT).show();
}
}
public boolean isCameraAvailable() {
PackageManager pm = getPackageManager();
return pm.hasSystemFeature(PackageManager.FEATURE_CAMERA);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case ZBAR_SCANNER_REQUEST:
case ZBAR_QR_SCANNER_REQUEST:
if (resultCode == RESULT_OK) {
mBarcodeEdit.setText(data.getStringExtra(ZBarConstants.SCAN_RESULT));
// Toast.makeText(this, "Scan Result = " + data.getStringExtra(ZBarConstants.SCAN_RESULT), Toast.LENGTH_SHORT).show();
} else if (resultCode == RESULT_CANCELED && data != null) {
String error = data.getStringExtra(ZBarConstants.ERROR_INFO);
if (!TextUtils.isEmpty(error)) {
Toast.makeText(this, error, Toast.LENGTH_SHORT).show();
}
}
break;
}
}
private static String validateFields(String barcode, String format,
String title, String price) {
StringBuilder errors = new StringBuilder();
if (barcode.matches("^\\s*$")) {
errors.append("Barcode required\n");
}
if (format.matches("^\\s*$")) {
errors.append("Format required\n");
}
if (title.matches("^\\s*$")) {
errors.append("Title required\n");
}
if (!price.matches("^-?\\d+(.\\d+)?$")) {
errors.append("Need numeric price\n");
}
return errors.toString();
}
}
I think string may be null somewhere. Please type something in textfield or check for null string.
I think ive looked at almost all threads wont seem to work.
Ive got a chat and im trying to update the list view every second im doing it on another thread however, im using runOnUiThread though it still wont update im logging the return and it seems there is a return every second with the correct data.
The code
protected void onCreate(Bundle savedInstanceState) {
........
lv = (ListView) findViewById(R.id.message_array);
returnFunc = "messages";
messages();
send = (ImageButton) findViewById(R.id.sendMessage);
send.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
returnFunc = "btnSend";
message = (EditText) findViewById(R.id.messageEditText);
message_input = message.getText().toString();
sendMessage();
}
});
new Thread(new Runnable() {
#Override
public void run() {
boolean test = true;
while (test) {
try {
Thread.sleep(1000);
} catch (Exception e) {
}
messages();
}
}
}).start();
}
public static Handler handler = new Handler();
public void messageLoop(){
handler.postDelayed(new Runnable() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
messages();
handler.postDelayed(this,1000);
}
});
}
},1000);
}
the messages function which gets the data fine
public void messages() {
String urlParameters = String.format("%s", "chatid="+tempVars.chatID+"&token="+tempVars.token);
new AsyncHttpPost(this).execute("http://mylink.com/appAccess.php?action=messages&", urlParameters);
}
public void getMessages(String content){
myList = new ArrayList<Messages>();
int index = lv.getFirstVisiblePosition();
View v = lv.getChildAt(0);
int top = (v == null) ? 0 : (v.getTop() - lv.getPaddingTop());
try{
JSONArray jsonarray = new JSONArray(content);
for (int i = 0; i < jsonarray.length(); i++) {
JSONObject jsonobject = jsonarray.getJSONObject(i);
boolean mine;
if(jsonobject.getString("isMine").equals("true")){
mine = true;
}else{
mine = false;
}
myList.add(new Messages(jsonobject.getString("message"),jsonobject.getString("timestamp"),jsonobject.getString("name"),mine,jsonobject.getString("id")));
}
}catch (Throwable tx){
}
lv.setOnItemClickListener(new AdapterView.OnItemClickListener()
{
#Override
public void onItemClick(AdapterView<?> adapter, View v, int position, long arg3)
{
Messages CurrentMessage = myList.get(position);
tempVars.messageID = CurrentMessage.getID();
//startActivity(new Intent("PersonalChat"));
}
});
if(arrayAdapter == null){
arrayAdapter = new CustomAdapter(this, myList);
}
lv = (ListView) findViewById(R.id.message_array);
lv.setAdapter(arrayAdapter);
arrayAdapter.notifyDataSetChanged();
if(firstView == 0){
firstView = 1;
lv.setSelection(arrayAdapter.getCount() - 1);
}else{
lv.setSelectionFromTop(index, top);
}
}
class CustomAdapter
public class CustomAdapter extends ArrayAdapter<Messages>{
Messages currentMessage;
public CustomAdapter(Context context, ArrayList<Messages> messages){
super(context,R.layout.received_message, messages);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View itemView = convertView;
currentMessage = myList.get(position);
setTitle(currentMessage.getName());
if(currentMessage.isMine()){
itemView = getLayoutInflater().inflate(R.layout.sent_message,parent, false);
TextView message = (TextView) itemView.findViewById(R.id.message);
message.setText(currentMessage.getMessage());
TextView timestamp = (TextView) itemView.findViewById(R.id.date);
timestamp.setText(currentMessage.getTimestamp());
}else{
itemView = getLayoutInflater().inflate(R.layout.received_message,parent, false);
TextView message = (TextView) itemView.findViewById(R.id.message_text);
message.setText(currentMessage.getMessage());
TextView timestamp = (TextView) itemView.findViewById(R.id.timestamp);
timestamp.setText(currentMessage.getTimestamp());
}
return itemView;
}
}
Thanks in advance
More info
When i call the message function originally in onCreate it works fine
new Thread(new Runnable() {
#Override
public void run() {
boolean test = true;
while (test) {
try {
Thread.sleep(1000);
} catch (Exception e) {
}mymessage();
}
}
}).start();
Replace your getMessages() method with below code:
public void getMessages(String content){
myList = new ArrayList<Messages>();
int index = lv.getFirstVisiblePosition();
View v = lv.getChildAt(0);
int top = (v == null) ? 0 : (v.getTop() - lv.getPaddingTop());
try{
JSONArray jsonarray = new JSONArray(content);
for (int i = 0; i < jsonarray.length(); i++) {
JSONObject jsonobject = jsonarray.getJSONObject(i);
boolean mine;
if(jsonobject.getString("isMine").equals("true")){
mine = true;
}else{
mine = false;
}
myList.add(new Messages(jsonobject.getString("message"),jsonobject.getString("timestamp"),jsonobject.getString("name"),mine,jsonobject.getString("id")));
}
arrayAdapter.notifyDataSetChanged();
}catch (Throwable tx){
}
lv.setOnItemClickListener(new AdapterView.OnItemClickListener()
{
#Override
public void onItemClick(AdapterView<?> adapter, View v, int position, long arg3)
{
Messages CurrentMessage = myList.get(position);
tempVars.messageID = CurrentMessage.getID();
//startActivity(new Intent("PersonalChat"));
}
});
if(arrayAdapter == null){
arrayAdapter = new CustomAdapter(this, myList);
}
lv = (ListView) findViewById(R.id.message_array);
lv.setAdapter(arrayAdapter);
if(firstView == 0){
firstView = 1;
lv.setSelection(arrayAdapter.getCount() - 1);
}else{
lv.setSelectionFromTop(index, top);
}
}