I have added navigation view and drawer layout in my app. When I open and close the drawer it lags in time. opens and close slowly. I got this issue prominently on version 4.4 also on 6.0 but not as prominently as 4.4.
When I am running on 4.4 device as I open the drawer I noticed messages in log that too much work may be doing on main thread.
So I tried to comment all the code except the navigation drawer and options menu code. So after that I found it was working bit well.
Is it the issue? or some memory issue can be there? But on larger memory devices also I found the problem.
Do I need to create another activity for other code? So that drawer will work faster?
I also tried to create a fragment and replaced it in framelayout of main activity to separate the code. But it was still lagging.
If I create new activity still I need all the navigation code in that activity, it will be again a same thing.
I am not getting what can be the issue. Can anyone please help.. Thank you..
Here is code:
public class MainActivity extends AppCompatActivity implements GetContactsAsyncTask.ContactGetCallBack,UpdateUserAsyncTask.UpdateUserCallBack {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
contactDb = new ContactTableHelper(MainActivity.this);
mDb = new UserTableHelper(MainActivity.this);
boolean result = Utility.checkAndRequestPermissions(MainActivity.this);
LocalBroadcastManager.getInstance(this).registerReceiver(mRegistrationBroadcastReceiver,
new IntentFilter(REGISTRATION_COMPLETE));
LocalBroadcastManager.getInstance(this).registerReceiver(mRegistrationBroadcastReceiver,
new IntentFilter(PUSH_NOTIFICATION));
NotificationUtils.clearNotifications(getApplicationContext());
sharedpreferences = getSharedPreferences("UserProfile", Context.MODE_PRIVATE);
mUserId = sharedpreferences.getString("userId", "");
firstTimeLogin = sharedpreferences.getBoolean("login", false);
refreshedToken = sharedpreferences.getString("deviceId", "");
parentLayout = (LinearLayout) findViewById(R.id.toolbar_container);
setupView();
mUser = new User();
url = sharedpreferences.getString("url", "");
contactList = new ArrayList<Contact>();
txtuserName = (TextView) findViewById(R.id.txtusername);
txtmobile = (TextView) findViewById(R.id.txtmobile);
profileImageView = (CircleImageView) findViewById(R.id.thumbnail);
if (profileImageView != null) {
profileImageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
drawerLayout.closeDrawers();
Intent Intent = new Intent(MainActivity.this, ProfileActivity.class);
Intent.putExtra("user", mUser);
Intent.putExtra("url", url);
startActivity(Intent);
}
});
}
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
Bitmap bitmap = BitmapFactory.decodeFile(image.getPath(), bmOptions);
if (bitmap != null) {
profileImageView.setImageBitmap(bitmap);
} else {
profileImageView.setImageDrawable(ContextCompat.getDrawable(MainActivity.this, R.drawable.ic_account_circle_white_48dp));
}
ImageView sync = (ImageView) findViewById(R.id.sync);
sync.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
contactList.clear();
contactDb.deleteAllContacts();
GetContactsAsyncTask getContactsAsyncTask = new GetContactsAsyncTask(MainActivity.this, MainActivity.this, mUserId, MainActivity.this);
getContactsAsyncTask.execute(mUserId);
}
});
}
void setupView() {
File sd = Environment.getExternalStorageDirectory();
image = new File(sd + "/Profile", "Profile_Image.png");
drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
navigationView = (NavigationView) findViewById(R.id.navigation_view);
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
drawerLayout.closeDrawers();
menuItem.setChecked(true);
FragmentManager fragmentManager = getSupportFragmentManager();
switch (menuItem.getItemId()) {
case R.id.nav_menu_contacts:
fragmentManager.beginTransaction().replace(R.id.container, fragment).commit();
break;
case R.id.nav_menu_settings:
Intent i = new Intent(MainActivity.this, PreferencesActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
startActivity(i);
break;
case R.id.nav_log_out:
SharedPreferences pref = getSharedPreferences("UserProfile", MODE_PRIVATE);
SharedPreferences.Editor editor = pref.edit();
editor.remove("UserUsername");
editor.remove("userId");
editor.remove("url");
editor.remove("login");
editor.remove("company");
editor.remove("emailId");
editor.remove("profileImage");
editor.remove("fullName");
editor.remove("homeAddress");
editor.remove("workAddress");
editor.remove("workPhone");
editor.remove("pass");
editor.remove("jobTitle");
editor.remove("mobileNo");
editor.commit();
mDb.deleteAllUsers();
contactDb.deleteAllContacts();
UpdateTokenAsyncTask updateTokenAsyncTask = new UpdateTokenAsyncTask(MainActivity.this, mUserId, "");
updateTokenAsyncTask.execute(mUserId, "");
finish();
i = new Intent(MainActivity.this, LoginActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
i.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
startActivity(i);
break;
case R.id.nav_invite:
i = new Intent(MainActivity.this, InviteContactsActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
startActivity(i);
break;
}
return true;
}
});
Toolbar toolbar = (Toolbar) findViewById(R.id.main_toolbar);
TextView mTitle = (TextView) findViewById(R.id.toolbar_title);
final ImageView menu = (ImageView) findViewById(R.id.menu);
menu.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
PopupMenu popup = new PopupMenu(MainActivity.this, menu);
popup.getMenuInflater().inflate(R.menu.main_pop_up_menu, popup.getMenu());
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
public boolean onMenuItemClick(MenuItem item) {
if (item.getItemId() == R.id.pendingInvites) {
startActivity(new Intent(MainActivity.this, PendingInvitesActivity.class));
} else if (item.getItemId() == R.id.feedback) {
final MaterialDialog dialog = new MaterialDialog.Builder(MainActivity.this)
.title("Feedback")
.customView(R.layout.feedback_dialog, true).build();
positiveAction = dialog.getActionButton(DialogAction.POSITIVE);
edtName = (EditText) dialog.getCustomView().findViewById(R.id.editName);
edtEmailId = (EditText) dialog.getCustomView().findViewById(R.id.editTextEmailId);
edtComment = (EditText) dialog.getCustomView().findViewById(R.id.editTextComment);
buttonSave = (Button) dialog.getCustomView().findViewById(R.id.buttonSave);
buttonSave.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
View view1 = getCurrentFocus();
if (view1 != null) {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view1.getWindowToken(), 0);
}
mName = String.valueOf(edtName.getText().toString());
mEmailId = String.valueOf(edtEmailId.getText().toString());
mComment = String.valueOf(edtComment.getText().toString());
if (mComment.equals("")) {
showAlert("Please enter comments.");
} else if (mEmailId.equals("")) {
showAlert("Please enter an email-id.");
} else {
if (!isValidEmail(mEmailId)) {
showAlert("Please enter valid email id.");
} else {
HashMap<String, String> params = new HashMap<String, String>();
params.put("name", mName);
params.put("email_id", mEmailId);
params.put("comment", mComment);
CreateFeedbackAsyncTask createFeedbackAsyncTask = new CreateFeedbackAsyncTask(MainActivity.this, MainActivity.this);
createFeedbackAsyncTask.execute(params);
dialog.dismiss();
}
}
}
});
edtName.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
positiveAction.setEnabled(s.toString().trim().length() > 0);
}
@Override
public void afterTextChanged(Editable s) {
View view = getCurrentFocus();
if (view != null) {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
}
});
edtComment.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
positiveAction.setEnabled(s.toString().trim().length() > 0);
View view = getCurrentFocus();
if (view != null) {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
}
@Override
public void afterTextChanged(Editable s) {
}
});
edtEmailId.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
positiveAction.setEnabled(s.toString().trim().length() > 0);
View view = getCurrentFocus();
if (view != null) {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
}
@Override
public void afterTextChanged(Editable s) {
}
});
dialog.show();
positiveAction.setEnabled(false);
return true;
}
return true;
}
});
popup.show();//showing popup menu
}
});
if (toolbar != null) {
toolbar.setTitle("");
setSupportActionBar(toolbar);
}
if (toolbar != null) {
toolbar.setNavigationIcon(R.drawable.ic_menu_white_24dp);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
drawerLayout.openDrawer(GravityCompat.START);
}
});
}
}
@Override
public void doPostExecute(JSONArray response) throws JSONException {
contactListArray = response;
contactDb = new ContactTableHelper(MainActivity.this);
if (null == contactList) {
contactList = new ArrayList<Contact>();
}
for (int i = 0; i < contactListArray.length(); i++) {
JSONObject subObject1 = contactListArray.getJSONObject(i);
Contact contact = new Contact();
JSONObject subObject = subObject1;
String contactName = subObject.getString("user_name");
//name of the attribute in response
String pass = subObject.getString("password");
String contactId = subObject.getString("user_id");
String contactMobile = subObject.getString("mobile_no");
String contactEmailId = subObject.getString("email_id");
String contactProfile = subObject.getString("profile_image");
String fullName = subObject.getString("full_name");
String jobTitle = subObject.getString("job_title");
String homeAddress = subObject.getString("home_address");
String workPhone = subObject.getString("work_phone");
String workAddress = subObject.getString("work_address");
String company = subObject.getString("company");
contact.setmThumbnail(contactProfile);
contact.setmUserName(contactName);
contact.setmMobileNo(contactMobile);
contact.setmEmailId(contactEmailId);
contact.setmProfileImage(contactProfile);
contact.setContactId(contactId);
contact.setmHomeAddress(homeAddress);
contact.setmFullName(fullName);
contact.setmJobTitle(jobTitle);
contact.setmWorkAddress(workAddress);
contact.setmWorkPhone(workPhone);
contact.setmPass(pass);
contact.setmCompany(company);
contactList.add(contact);//adding string to arraylist
contactDb.addContact(new Contact(contactId, contactName, pass, contactMobile, contactEmailId, contactProfile, fullName, jobTitle, workAddress, workPhone, homeAddress, company));
}
adapter = new ContactAdapter(MainActivity.this, contactList);
recyclerView.setAdapter(adapter);
recyclerView.setHasFixedSize(true);
recyclerView.setItemViewCacheSize(20);
recyclerView.setDrawingCacheEnabled(true);
recyclerView.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
}
@Override
public void onResume() {
super.onResume();
contactList.clear();
if (!firstTimeLogin) {
contactList.clear();
contactList = contactDb.getAllContacts();
mUser = mDb.getUser(mUserId);
txtuserName.setText(mUser.getmUserName());
txtmobile.setText(mUser.getmMobileNo());
} else {
new GetUserAsyncTask1(MainActivity.this,mUserId).execute(mUserId);
new GetContactsAsyncTask(this, MainActivity.this, mUserId, MainActivity.this).execute();
firstTimeLogin = false;
SharedPreferences.Editor editor = getSharedPreferences("UserProfile", MODE_PRIVATE).edit();
editor.putBoolean("login", firstTimeLogin);
editor.commit();
}
recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
recyclerView.setHasFixedSize(true);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(MainActivity.this);
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.addItemDecoration(new DividerItemDecoration(this, LinearLayoutManager.VERTICAL));
recyclerView.setItemAnimator(new DefaultItemAnimator());
adapter = new ContactAdapter(MainActivity.this, contactList);
recyclerView.setAdapter(adapter);
recyclerView.addOnItemTouchListener(new RecyclerTouchListener(MainActivity.this, recyclerView, new ClickListener() {
@Override
public void onClick(View view, int position) {
final Contact contact = contactList.get(position);
}
@Override
public void onLongClick(View view, int position) {
}
}));
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case REQUEST_ID_MULTIPLE_PERMISSIONS: {
Map<String, Integer> perms = new HashMap<String, Integer>();
perms.put(Manifest.permission.WRITE_EXTERNAL_STORAGE, PackageManager.PERMISSION_GRANTED);
perms.put(Manifest.permission.CAMERA, PackageManager.PERMISSION_GRANTED);
perms.put(Manifest.permission.READ_CONTACTS, PackageManager.PERMISSION_GRANTED);
perms.put(Manifest.permission.SEND_SMS, PackageManager.PERMISSION_GRANTED);
for (int i = 0; i < permissions.length; i++)
perms.put(permissions[i], grantResults[i]);
if (perms.get(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED
&& perms.get(Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_GRANTED
&& perms.get(Manifest.permission.SEND_SMS) == PackageManager.PERMISSION_GRANTED
&& perms.get(Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
} else {
showAlert("Some Permissions are Denied.");
}
}
break;
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
@Override
public void doPostExecute(JSONObject response, Boolean update) throws JSONException {
}
}
Main layout :
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/container">
</FrameLayout>
<!-- Your normal content view -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:id = "@+id/toolbar_container">
<!-- We use a Toolbar so that our drawer can be displayed
in front of the action bar -->
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/main_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light">
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/Contacts"
android:layout_gravity="center"
android:id="@+id/toolbar_title"
android:textSize="20sp"
android:textColor="#ffffff"
android:textStyle="bold"
android:textAlignment="center"
android:gravity="center_vertical|center|center_horizontal"
android:layout_toLeftOf="@+id/sync"
android:layout_toStartOf="@+id/sync"
android:layout_centerInParent="true"
android:layout_marginLeft="30dp"
android:layout_marginRight="10dp" />
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:background="@drawable/ic_refresh_white_24dp"
android:id="@+id/sync"
android:layout_gravity = "right"
android:layout_toStartOf="@+id/menu"
android:layout_toLeftOf="@+id/menu"
android:layout_centerVertical="true"
android:layout_alignParentRight="false"
android:layout_marginRight="10dp" />
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity= "end"
android:layout_marginRight="10dp"
android:background="@drawable/ic_more_vert_white_36dp"
android:id="@+id/menu"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_alignParentRight="true" />
</RelativeLayout>
</android.support.v7.widget.Toolbar>
<view
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
class="android.support.v7.widget.RecyclerView"
android:id="@+id/recycler_view"
android:layout_alignParentStart="true"
android:layout_alignParentLeft="true" />
<!-- The rest of your content view -->
</LinearLayout>
<android.support.design.widget.NavigationView
android:id="@+id/navigation_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="?attr/colorPrimary"
app:headerLayout="@layout/drawer_header"
app:itemTextColor="@color/yourColor"
app:itemIconTint="@color/yourColor"
app:menu="@menu/nav_menu" >
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<include
layout="@layout/drawer_header"
android:layout_width="match_parent"
android:layout_height="103dp" />
<ExpandableListView
android:id="@+id/elvGuideNavigation"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:groupIndicator="@null"
/>
</LinearLayout>
</android.support.design.widget.NavigationView>
Do the Json Parsing and adding the Entries into the DB also in Background Thread and Pass only the ArrayList of Entries to the Main Thread, this way you can reduce the Load on the Main Thread.
Another thing you can try is Enabling hardwareAcceleration to true