I have a problem every time i open an activity (blueToothSearch.java) the following error occurs in my logcat.
12-04 18:57:52.317 5354-5354/com.example.admin.paniccenter E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.admin.paniccenter, PID: 5354
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.admin.paniccenter/com.example.admin.paniccenter.blueToothSearch}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.content.Context.getApplicationContext()' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2327)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.content.Context.getApplicationContext()' on a null object reference
at org.altbeacon.beacon.BeaconManager.<init>(BeaconManager.java:323)
at org.altbeacon.beacon.BeaconManager.getInstanceForApplication(BeaconManager.java:315)
at com.example.admin.paniccenter.blueToothSearch.<init>(blueToothSearch.java:65)
at java.lang.Class.newInstance(Native Method)
at android.app.Instrumentation.newActivity(Instrumentation.java:1067)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2317)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Below is my blueToothSearch activity which i want to use to display a list of beacons in my region.
public class blueToothSearch extends AppCompatActivity implements BeaconConsumer {
private static final String TAG = "blueToothSearch";
private ViewPagerAdapter viewadapter;
private ViewPager myViewPager;
private TabLayout tabLayout;
public Toolbar toolbar;
//public static Handler UIHandler;
private static final int REQUEST_ENABLE_BT = 1234;
//public static final String EXTRAS_TARGET_ACTIVITY = "extrasTargetActivity";
//private static final String JAALEE_BEACON_PROXIMITY_UUID = "EBEFD083-70A2-47C8-9837-E7B5634DF524";//Jaalee BEACON Default UUID
// private static final Region ALL_BEACONS_REGION = new Region("rid", null, null, null);
//public static final String EXTRAS_BEACON = "extrasBeacon";
public BeaconManager beaconManager = BeaconManager.getInstanceForApplication(getBaseContext());
private ArrayList<Beacon> arrayL = new ArrayList<Beacon>();
private BeaconServiceUtility beaconUtill = null;
private BeaconAdapter adapterr;
public ListView list;
private LayoutInflater inflater;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_navigation);
viewadapter = new ViewPagerAdapter(getSupportFragmentManager());
toolbar = (Toolbar)findViewById(R.id.toolbar);
toolbar.setTitle("Bluetooth Devices");
//Set up the View Pager with the View page adapter
myViewPager = (ViewPager)findViewById(R.id.viewpager);
tabLayout = (TabLayout)findViewById(R.id.tabs);
tabLayout.setupWithViewPager(myViewPager);
//tabLayout.setVisibility(View.GONE);
final FloatingActionButton fab = (FloatingActionButton)findViewById(R.id.fab);
fab.setImageResource(R.drawable.ic_popup_sync_24);
setupViewPager(myViewPager);
setSupportActionBar(toolbar);
//viewPager.setAdapter(adapter);
myViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
switch (position){
case 0: fab.show();
break;
case 1: fab.hide();
break;
}
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
//getSupportActionBar().setDisplayShowHomeEnabled(true);
final DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
finish();
drawer.closeDrawer(Gravity.LEFT);
}
});
adapterr = new BeaconAdapter();
list = findViewById(R.id.beaconlist);
list.setAdapter(adapterr);
//list.setOnItemClickListener(createOnItemClickListener());
inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
private void setupViewPager(ViewPager viewPager){
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFragment(new blueToothSearch.bluetooth(), "Available Devices");
adapter.addFragment(new bluetoothProperties(), "Device Properties");
viewPager.setAdapter(adapter);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if(requestCode == REQUEST_ENABLE_BT){
if (resultCode == Activity.RESULT_OK){
connectToService();
}else {
Toast.makeText(this, "Bluetooth not enabled", Toast.LENGTH_LONG).show();
getSupportActionBar().setSubtitle("Bluetooth not enabled");
}
}
super.onActivityResult(requestCode, resultCode, data);
}
private void connectToService(){
try {
beaconManager.startRangingBeaconsInRegion(new Region("myRangingUniqueId", null, null, null));
}catch (RemoteException e){
e.printStackTrace();
}
try {
beaconManager.startMonitoringBeaconsInRegion(new Region("myMonitoringUniqueId", null, null, null));
}catch (RemoteException e){
e.printStackTrace();
}
}
/**
private AdapterView.OnItemClickListener createOnItemClickListener(){
return new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int pos, long l) {
if (getIntent().getStringExtra(EXTRAS_TARGET_ACTIVITY) != null){
try {
Class<?> clazz = Class.forName(getIntent().getStringExtra(EXTRAS_TARGET_ACTIVITY));
Intent intent = new Intent(blueToothSearch.this, clazz );
Beacon temp = adapterr.getItem(pos);
intent.putExtra(EXTRAS_BEACON, temp);
if(getIntent().getStringExtra(EXTRAS_TARGET_ACTIVITY).contains("com.example.admin.paniccenter.CharacteristicsDemoActivity"))
{
startActivity(intent);
// if (temp.getProximityUUID().equalsIgnoreCase(JAALEE_BEACON_PROXIMITY_UUID)) {
// startActivity(intent);
// }
// else
// {
// ListBeaconsActivity.this.runOnUiThread(new Runnable()
//{
// public void run()
// {
//Toast.makeText(ListBeaconsActivity.this, "Current Beacon is in Non-Connectable mode", Toast.LENGTH_LONG).show();
// }
// });
// }
}
else
{
startActivity(intent);
}
}catch (ClassNotFoundException e){
Log.e(TAG, "Finding class by name failed", e);
}
}
}
};
}
*/
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.scan_menu, menu);
MenuItem refreshItem = menu.findItem(R.id.refresh);
refreshItem.setActionView(R.layout.actionbar_indeterminate_progress);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onStart() {
super.onStart();
beaconUtill.onStart(beaconManager, this);
}
#Override
public void onStop() {
beaconUtill.onStop(beaconManager, this);
super.onStop();
}
#Override
public void onDestroy() {
super.onDestroy();
}
#Override
public void onBeaconServiceConnect() {
getSupportActionBar().setSubtitle("Scanning...");
Toast.makeText(this, "Scanning for devices", Toast.LENGTH_LONG).show();
beaconManager.setRangeNotifier(new RangeNotifier() {
#Override
public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {
arrayL.clear();
arrayL.addAll((ArrayList<Beacon>) beacons);
adapterr.notifyDataSetChanged();
}
});
beaconManager.setMonitorNotifier(new MonitorNotifier() {
#Override
public void didEnterRegion(Region region) {
Log.e("BeaconDetactorService", "didEnterRegion");
}
#Override
public void didExitRegion(Region region) {
Log.e("BeaconDetactorService", "didExitRegion");
}
#Override
public void didDetermineStateForRegion(int i, Region region) {
Log.e("BeaconDetactorService", "didDetermineStateForRegion");
}
});
connectToService();
}
public static class bluetooth extends Fragment {
private static final String TAG = "bluetooth";
private int position;
private TextView textv;
private ViewPagerAdapter viewadapter;
private ViewPager myViewPager;
private TabLayout tabLayout;
private FragmentActivity myContext;
#Override
public void onAttach(Context context) {
super.onAttach(context);
//hideAction = (HideActionBar)getContext();
myContext = (FragmentActivity)getContext();
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//position = getArguments().getInt("pos");
//toolbar.getMenu().clear();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//return inflater.inflate(R.layout.fragment_bluetooth_search, container, false);
View view = inflater.inflate(R.layout.fragment_bluetooth_search, container, false);
//TextView text = (TextView)getActivity().findViewById(R.id.view);
//text.setText("i am the real text ");
//hideAction.customBlueToothToolbar();
//FloatingActionButton fl = (FloatingActionButton)getActivity().findViewById(R.id.fab);
//fl.setImageResource(R.drawable.ic_popup_sync_24);
return view;
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
}
public class BeaconAdapter extends BaseAdapter {
private ArrayList<Beacon> beacons;
#Override
public int getCount() {
return arrayL.size();
}
#Override
public Beacon getItem(int arg0) {
return arrayL.get(arg0);
}
#Override
public long getItemId(int arg0) {
return arg0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
try {
ViewHolder holder;
if (convertView != null) {
holder = (ViewHolder) convertView.getTag();
} else {
holder = new ViewHolder(convertView = inflater.inflate(R.layout.tupple_monitoring, null));
}
if (beacons.get(position).getParserIdentifier() != null)
holder.beacon_uuid.setText("UUID: " + arrayL.get(position).getParserIdentifier());
holder.beacon_major.setText("Major: " + arrayL.get(position).getBeaconTypeCode());
holder.beacon_minor.setText(", Minor: " + arrayL.get(position).getBluetoothName());
holder.beacon_proximity.setText("Proximity: " + arrayL.get(position).getDistance());
holder.beacon_rssi.setText(", Rssi: " + arrayL.get(position).getRssi());
holder.beacon_txpower.setText(", TxPower: " + arrayL.get(position).getTxPower());
holder.beacon_range.setText("" + arrayL.get(position).getExtraDataFields());
} catch (Exception e) {
e.printStackTrace();
}
return convertView;
}
private class ViewHolder {
private TextView beacon_uuid;
private TextView beacon_major;
private TextView beacon_minor;
private TextView beacon_proximity;
private TextView beacon_rssi;
private TextView beacon_txpower;
private TextView beacon_range;
public ViewHolder(View view) {
beacon_uuid = (TextView) view.findViewById(R.id.BEACON_uuid);
beacon_major = (TextView) view.findViewById(R.id.BEACON_major);
beacon_minor = (TextView) view.findViewById(R.id.BEACON_minor);
beacon_proximity = (TextView) view.findViewById(R.id.BEACON_proximity);
beacon_rssi = (TextView) view.findViewById(R.id.BEACON_rssi);
beacon_txpower = (TextView) view.findViewById(R.id.BEACON_txpower);
beacon_range = (TextView) view.findViewById(R.id.BEACON_range);
view.setTag(this);
}
}
}
I am using a BeaconManager class to range and scan my beacons, the library is from package org.altbeacon.beacon
Related
I have been trying to implement search using firestoreUI but when i run my code the logcat says that:
java.lang.NullPointerException: Attempt to invoke virtual method 'void com.firebase.ui.firestore.FirestoreRecyclerAdapter.startListening()' on a null object reference
at com.example.homebarberv1.Search.onStart(Search.java:93)
below is my code:
public class Search extends AppCompatActivity implements FirebaseAuth.AuthStateListener{
private EditText searchField;
private Button searchButton;
private RecyclerView searchRecyclerview;
private FirebaseAuth firebaseAuth = FirebaseAuth.getInstance();
private FirestoreRecyclerAdapter<User, UsersViewHolder> adapter;
private String searchText;
static {
FirebaseFirestore.setLoggingEnabled(true);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getSupportActionBar().hide();
setContentView(R.layout.activity_search);
searchField = findViewById(R.id.SearchField);
searchButton = findViewById(R.id.SearchButton);
searchRecyclerview = findViewById(R.id.SearchContainer);
LinearLayoutManager manager = new LinearLayoutManager(this);
manager.setReverseLayout(true);
manager.setStackFromEnd(true);
searchRecyclerview .setHasFixedSize(true);
searchRecyclerview .setLayoutManager(manager);
BottomNavigationView bottomNavigationView = findViewById(R.id.bottomNavigationView);
bottomNavigationView.setSelectedItemId(R.id.search);
bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()){
case R.id.search:
return true;
case R.id.appointment:
startActivity(new Intent(getApplicationContext(),HomePage.class));
overridePendingTransition(0,0);
return true;
case R.id.profile:
startActivity(new Intent(getApplicationContext(),Profile.class));
overridePendingTransition(0,0);
return true;
}
return false;
}
});
searchButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
searchText = searchField.getText().toString();
firebaseUserSearch(searchText);
}
});
}
#Override
public void onStart() {
super.onStart();
if (isSignedIn()) {
adapter.startListening();
}
firebaseAuth.addAuthStateListener(this);
}
#Override
protected void onStop() {
super.onStop();
adapter.stopListening();
FirebaseAuth.getInstance().removeAuthStateListener(this);
}
#Override
public void onAuthStateChanged(#NonNull FirebaseAuth auth) {
if (isSignedIn()) {
adapter.startListening();
} else {
Toast.makeText(Search.this,"user are not signed in",Toast.LENGTH_LONG);
}
}
private boolean isSignedIn() {
return FirebaseAuth.getInstance().getCurrentUser() != null;
}
#NonNull
private void firebaseUserSearch(String searchText){
CollectionReference sCollection =
FirebaseFirestore.getInstance().collection("Barbers");
Query sQuery = sCollection.startAt(searchText).endAt(searchText + "\uf8ff");
FirestoreRecyclerOptions<User> options =
new FirestoreRecyclerOptions.Builder<User>()
.setQuery(sQuery, User.class)
.setLifecycleOwner(this)
.build();
adapter = new FirestoreRecyclerAdapter<User, UsersViewHolder>(options) {
#NonNull
#Override
public UsersViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.searchlist, parent, false);
return new UsersViewHolder(view);
}
#Override
protected void onBindViewHolder(#NonNull UsersViewHolder holder, int position, #NonNull User model) {
holder.setName(model.getShopname());
holder.setPic(model.getPiclink());
holder.setAddress(model.getAddress() + ", " + model.getPostcode().toString() + ", " + model.getCity());
}
};
searchRecyclerview.setAdapter(adapter);
}
public class UsersViewHolder extends RecyclerView.ViewHolder {
private View mView;
public UsersViewHolder(View itemView) {
super(itemView);
mView = itemView;
}
public void setName(String name){
TextView userNameView = (TextView) mView.findViewById(R.id.shopNameS);
userNameView.setText(name);
}
public void setPic(String link){
ImageView imageView = (ImageView)mView.findViewById(R.id.imageS);
Picasso.get().load(link).into(imageView);
}
public void setAddress(String address){
TextView addressView = (TextView) mView.findViewById(R.id.shopAddressS);
addressView.setText(address);
}
}
}
the error refers to this line:
adapter.startListening();
I'm still new to Android, so I do not really understand what I'm doing wrong here, help is really appreciated
You need to ensure that adapter has been given a value, before you call adapter.startListening on it.
That means that in onStart you need to ensure the adapter exists:
#Override
public void onStart() {
super.onStart();
if (isSignedIn() && adapter != null) {
adapter.startListening();
}
firebaseAuth.addAuthStateListener(this);
}
And then also start listening on the adapter when you create it and the user is signed in. So:
adapter = new FirestoreRecyclerAdapter<User, UsersViewHolder>(options) {
...
});
if (isSignedIn()) {
adapter.startListening();
}
i'm from indonesia, i want to refresh a fragment after i insert a data to it.. i have try many times to refresh a fragment. but it can't work.
please help me..
here's my code..
class MainActivity
public class MainActivity extends FragmentActivity {
public MainActivity() {
}
DatabaseReference dataBaseref;
StorageReference strRef;
TextView logout;
TabLayout tabLayout;
ViewPager viewPager;
ViewPagerAdapter viewAdapter = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dataBaseref = FirebaseDatabase.getInstance().getReference();
strRef = FirebaseStorage.getInstance().getReference();
tabLayout = findViewById(R.id.tab_layout_isi_menu);
viewPager = findViewById(R.id.view_pager_isi_menu);
logout = findViewById(R.id.text_logout);
viewAdapter = new ViewPagerAdapter(getSupportFragmentManager(), MainActivity.this);
viewAdapter.addFragment(new isi_list_beli(), "Beli");
viewAdapter.addFragment(new isi_list_cek(), "Cek Data");
viewPager.setAdapter(viewAdapter);
tabLayout.setupWithViewPager(viewPager);
logout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
logOut();
}
});
}
private void logOut() {
AuthUI.getInstance()
.signOut(MainActivity.this)
.addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
startActivity(new Intent(MainActivity.this, LoginActivity.class));
finish();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(MainActivity.this, "" + e.getMessage(), Toast.LENGTH_LONG).show();
}
});
}
#Override
protected void onResume() {
super.onResume();
}
public void onBackPressed() {
super.finish();
}
}
class isi_list_cek
public class isi_list_cek extends Fragment {
private ListView listView;
public AdapterListCek adapterListCek = null;
private ArrayList<Cek> cekArrayList;
Cursor cursor;
View view;
FloatingActionButton fab;
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
adapterListCek = new AdapterListCek(getContext(), R.layout.item_in_list_barang, cekArrayList);
adapterListCek.notifyDataSetChanged();
}
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #NonNull Bundle savedInstanceState) {
view = inflater.inflate(R.layout.list_barang, container, false);
listView = view.findViewById(R.id.list_item_barang);
fab = view.findViewById(R.id.tambah_barang);
cekArrayList = new ArrayList<>();
adapterListCek = new AdapterListCek(getContext(), R.layout.item_in_list_barang, cekArrayList);
listView.setAdapter(adapterListCek);
cursor = fragment_input_data.sqlHelper.getData("SELECT * FROM CEK");
if(cursor.moveToFirst()){
cekArrayList.clear();
do{
int id = cursor.getInt(0);
String kode = cursor.getString(1);
String nama = cursor.getString(2);
String jumlah = cursor.getString(3);
String harga = cursor.getString(4);
byte[] gambar = cursor.getBlob(5);
cekArrayList.add(new Cek(id, kode, nama, harga, jumlah, gambar));
}while (cursor.moveToNext());
fragment_input_data.sqlHelper.close();
}
adapterListCek.notifyDataSetChanged();
listView.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View view) {
return false;
}
});
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
startActivity(new Intent(getContext(), fragment_input_data.class));
}
});
return view;
}
#Override
public void onResume() {
super.onResume();
}
}
class ViewPagerAdapter
public class ViewPagerAdapter extends FragmentStatePagerAdapter {
private Map<Integer, String> mFragmentTags;
private FragmentManager mFragmentManager;
private Context mContext;
private final List<Fragment> fragmentList = new ArrayList<>();
private final List<String> fragmentListTitle = new ArrayList<>();
public ViewPagerAdapter(FragmentManager fm, Context mContext) {
super(fm);
}
#Override
public Fragment getItem(int position) {
return fragmentList.get(position);
}
#Override
public int getCount() {
return fragmentListTitle.size();
//return 2;
}
#NonNull
#Override
public CharSequence getPageTitle(int position) {
return fragmentListTitle.get(position);
}
public void addFragment (Fragment fragment, String string){
fragmentList.add(fragment);
fragmentListTitle.add(string);
}
}
i expect when i insert some data, fragment will automatically update it's view.
call a function as: just send the new instance of present fragment that you want to recreate
replaceFragment(new YourPresentFragment());
the function can be as below:
private void replaceFragment(Fragment fragment) {
String fragmentTag = fragment.getClass().getName();
FragmentManager manager = getFragmentManager();
FragmentTransaction ft = manager.beginTransaction();
ft.replace(R.id.fragments, fragment, fragmentTag);
ft.addToBackStack("fragments");
ft.commit();
}
this should do the job
I am having four tab in my View pager I have search in google but I can,t found any solution when Swipe my view pager it work fine like 1-2-3-4 but when I try to swipe reverse 4-3-2-1 than my data get lost or you can say my adapter get lost.My View Pager is inside Activity.My Data is lost when I go to next page and back then back my data is lost.
My Main Activity is:
public class MainActivity extends AppCompatActivity {
public static int notificationCountCart = 0;
Toolbar toolbar;
ActionBar actionBar;
static ViewPager viewPager;
static TabLayout tabLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
if (toolbar != null)
setSupportActionBar(toolbar);
actionBar = getSupportActionBar();
if (actionBar != null) {
TextView textView = new TextView(this);
textView.setText("Shopping");
textView.setTextSize(20);
textView.setTypeface(null, Typeface.BOLD);
textView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
textView.setGravity(Gravity.CENTER);
textView.setTextColor(getResources().getColor(R.color.white));
getSupportActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
getSupportActionBar().setCustomView(textView);
actionBar.setDisplayShowTitleEnabled(false);
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeAsUpIndicator(new IconDrawable(this, FontAwesomeIcons.fa_angle_left).colorRes(R.color.white).actionBarSize());
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
viewPager = (ViewPager) findViewById(R.id.viewpagerrr);
tabLayout = (TabLayout) findViewById(R.id.tabs);
setupViewPager(viewPager);
tabLayout.setupWithViewPager(viewPager);
}
#Override
protected void onResume() {
super.onResume();
invalidateOptionsMenu();
}
#Override
public void onBackPressed() {
super.onBackPressed();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
// Get the notifications MenuItem and
// its LayerDrawable (layer-list)
MenuItem item = menu.findItem(R.id.action_cart);
NotificationCountSetClass.setAddToCart(MainActivity.this, item, notificationCountCart);
// force the ActionBar to relayout its MenuItems.
// onCreateOptionsMenu(Menu) will be called again.
invalidateOptionsMenu();
return super.onPrepareOptionsMenu(menu);
}
#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_search) {
startActivity(new Intent(MainActivity.this, SearchResultActivity.class));
return true;
} else if (id == R.id.action_cart) {
/* NotificationCountSetClass.setAddToCart(MainActivity.this, item, notificationCount);
invalidateOptionsMenu();*/
startActivity(new Intent(MainActivity.this, CartListActivity.class));
/* notificationCount=0;//clear notification count
invalidateOptionsMenu();*/
return true;
} else if (id == android.R.id.home) {
Intent intent = new Intent(MainActivity.this, HomeActivity.class);
startActivity(intent);
// startActivity(new Intent(MainActivity.this, EmptyActivity.class));
}
return super.onOptionsItemSelected(item);
}
private void setupViewPager(ViewPager viewPager) {
Adapter adapter = new Adapter(getSupportFragmentManager());
ImageListFragment fragment = new ImageListFragment();
SpeakerFragment speakerFragment = new SpeakerFragment();
adapter.addFragment(fragment, getString(R.string.item_2));
adapter.addFragment(speakerFragment, getString(R.string.item_4));
adapter.addFragment(new HeadPhone(), getString(R.string.item_3));
adapter.addFragment(new Offer(), getString(R.string.item_1));
viewPager.setAdapter(adapter);
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
}
static class Adapter extends FragmentPagerAdapter {
private final List<Fragment> mFragments = new ArrayList<>();
private final List<String> mFragmentTitles = new ArrayList<>();
public Adapter(FragmentManager fm) {
super(fm);
}
public void addFragment(Fragment fragment, String title) {
mFragments.add(fragment);
mFragmentTitles.add(title);
}
#Override
public Fragment getItem(int position) {
return mFragments.get(position);
}
#Override
public int getCount() {
return mFragments.size();
}
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitles.get(position);
}
}
}
My Fragment is
public class ImageListFragment extends Fragment {
String category_Name, Category_ID, Product_ID, Product_Name,
Product_Image, Product_Price, Product_Sale, Cart;
public static final String STRING_IMAGE_URI = "ImageUri";
public static final String STRING_IMAGE_POSITION = "ImagePosition";
private static MainActivity mActivity;
ArrayList<SingleItemModel> singleItemModels;
RecyclerView recyclerView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getCategoryone();
Fresco.initialize(getContext());
mActivity = (MainActivity) getActivity();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
recyclerView = (RecyclerView) inflater.inflate(R.layout.layout_recylerview_list, container, false);
return recyclerView;
}
public static class SimpleStringRecyclerViewAdapter
extends RecyclerView.Adapter<ImageListFragment.SimpleStringRecyclerViewAdapter.ViewHolder> {
// private String[] mValues;
private ArrayList<SingleItemModel> mValues;
private RecyclerView mRecyclerView;
public static class ViewHolder extends RecyclerView.ViewHolder {
public final View mView;
public final SimpleDraweeView mImageView;
public final LinearLayout mLayoutItem;
public final ImageView mImageViewWishlist;
TextView iTemName, itemDescription, itemPrice;
public ViewHolder(View view) {
super(view);
mView = view;
mImageView = (SimpleDraweeView) view.findViewById(R.id.image1);
mLayoutItem = (LinearLayout) view.findViewById(R.id.layout_item);
mImageViewWishlist = (ImageView) view.findViewById(R.id.ic_wishlist);
iTemName = (TextView) view.findViewById(R.id.itemName);
itemDescription = (TextView) view.findViewById(R.id.itemDescription);
itemPrice = (TextView) view.findViewById(R.id.itemPrice);
}
}
public SimpleStringRecyclerViewAdapter(RecyclerView recyclerView, ArrayList<SingleItemModel> items) {
mValues = items;
mRecyclerView = recyclerView;
}
#Override
public ImageListFragment.SimpleStringRecyclerViewAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, parent, false);
return new ImageListFragment.SimpleStringRecyclerViewAdapter.ViewHolder(view);
}
#Override
public void onViewRecycled(ImageListFragment.SimpleStringRecyclerViewAdapter.ViewHolder holder) {
if (holder.mImageView.getController() != null) {
holder.mImageView.getController().onDetach();
}
if (holder.mImageView.getTopLevelDrawable() != null) {
holder.mImageView.getTopLevelDrawable().setCallback(null);
//
}
}
#Override
public void onBindViewHolder(final ImageListFragment.SimpleStringRecyclerViewAdapter.ViewHolder holder, final int position) {
SingleItemModel singleItemModel = mValues.get(position);
holder.iTemName.setText(singleItemModel.getCategory_Name());
final Uri uri = Uri.parse(singleItemModel.getProduct_Image());
holder.mImageView.setImageURI(uri);
holder.itemPrice.setText(singleItemModel.getProduct_Price());
holder.itemDescription.setText(singleItemModel.getProduct_Sale());
}
#Override
public int getItemCount() {
return mValues.size();
}
}
public void getCategoryone() {
final RequestQueue queue = Volley.newRequestQueue(getActivity());
StringRequest stringRequest = new StringRequest(Request.Method.POST, "http://proaudiobrands.com/app/feature.php",
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.i("shabina shopping response", response);
try {
singleItemModels = new ArrayList<>();
JSONObject mainObj = new JSONObject(response);
Log.d("shabina ", response);
JSONArray Feature_product = mainObj.getJSONArray("Feature_product");
for (int i = 0; i < Feature_product.length(); i++) {
JSONObject Feature_Product = Feature_product.getJSONObject(i);
String Category_Namee = Feature_Product.getString("Category_Namee");
String Category_IDs = Feature_Product.getString("Category_IDs");
JSONArray Product_List = Feature_Product.getJSONArray("Product_List");
for (int j = 0; j < Product_List.length(); j++) {
JSONObject Category_Name = Product_List.getJSONObject(j);
if (Category_Name.getString("Category_Name").equals("Microphones")) {
category_Name = Category_Name.getString("Category_Name");
Category_ID = Category_Name.getString("Category_ID");
Product_ID = Category_Name.getString("Product_ID");
Product_Name = Category_Name.getString("Product_Name");
Product_Image = Category_Name.getString("Product_Image");
Product_Price = Category_Name.getString("Product_Price");
Product_Sale = Category_Name.getString("Product_Sale");
Cart = Category_Name.getString("Cart");
Log.e("sushil Category_Name", category_Name + " " + Category_ID + " " + Product_ID + " " + Product_Name + " " + Product_Image + " " + Product_Price + " " + Product_Sale + " " + Cart);
SingleItemModel singleItemModel1 = new SingleItemModel(category_Name, Category_ID, Product_ID, Product_Name, Product_Image, Product_Price, Product_Sale, Cart);
singleItemModels.add(singleItemModel1);
}
StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(new ImageListFragment.SimpleStringRecyclerViewAdapter(recyclerView, singleItemModels));
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("error", error.toString());
}
}) {
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<>();
params.put("method", "feature");
params.put("userId", "PRO1");
return params;
}
};
stringRequest.setRetryPolicy(new DefaultRetryPolicy(
90000,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
queue.add(stringRequest);
}
}
Replace your MainActivity with below
public class MainActivity extends AppCompatActivity {
public static int notificationCountCart = 0;
Toolbar toolbar;
ActionBar actionBar;
static ViewPager viewPager;
static TabLayout tabLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
if (toolbar != null)
setSupportActionBar(toolbar);
actionBar = getSupportActionBar();
if (actionBar != null) {
TextView textView = new TextView(this);
textView.setText("Shopping");
textView.setTextSize(20);
textView.setTypeface(null, Typeface.BOLD);
textView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
textView.setGravity(Gravity.CENTER);
textView.setTextColor(getResources().getColor(R.color.white));
getSupportActionBar().setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM);
getSupportActionBar().setCustomView(textView);
actionBar.setDisplayShowTitleEnabled(false);
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeAsUpIndicator(new IconDrawable(this, FontAwesomeIcons.fa_angle_left).colorRes(R.color.white).actionBarSize());
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
viewPager = (ViewPager) findViewById(R.id.viewpagerrr);
viewPager.setOffscreenPageLimit(4);
tabLayout = (TabLayout) findViewById(R.id.tabs);
setupViewPager(viewPager);
tabLayout.setupWithViewPager(viewPager);
}
#Override
protected void onResume() {
super.onResume();
invalidateOptionsMenu();
}
#Override
public void onBackPressed() {
super.onBackPressed();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
// Get the notifications MenuItem and
// its LayerDrawable (layer-list)
MenuItem item = menu.findItem(R.id.action_cart);
NotificationCountSetClass.setAddToCart(MainActivity.this, item, notificationCountCart);
// force the ActionBar to relayout its MenuItems.
// onCreateOptionsMenu(Menu) will be called again.
invalidateOptionsMenu();
return super.onPrepareOptionsMenu(menu);
}
#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_search) {
startActivity(new Intent(MainActivity.this, SearchResultActivity.class));
return true;
} else if (id == R.id.action_cart) {
/* NotificationCountSetClass.setAddToCart(MainActivity.this, item, notificationCount);
invalidateOptionsMenu();*/
startActivity(new Intent(MainActivity.this, CartListActivity.class));
/* notificationCount=0;//clear notification count
invalidateOptionsMenu();*/
return true;
} else if (id == android.R.id.home) {
Intent intent = new Intent(MainActivity.this, HomeActivity.class);
startActivity(intent);
// startActivity(new Intent(MainActivity.this, EmptyActivity.class));
}
return super.onOptionsItemSelected(item);
}
private void setupViewPager(ViewPager viewPager) {
Adapter adapter = new Adapter(getSupportFragmentManager());
ImageListFragment fragment = new ImageListFragment();
SpeakerFragment speakerFragment = new SpeakerFragment();
adapter.addFragment(fragment, getString(R.string.item_2));
adapter.addFragment(speakerFragment, getString(R.string.item_4));
adapter.addFragment(new HeadPhone(), getString(R.string.item_3));
adapter.addFragment(new Offer(), getString(R.string.item_1));
viewPager.setAdapter(adapter);
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
#Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
#Override
public void onPageSelected(int position) {
}
#Override
public void onPageScrollStateChanged(int state) {
}
});
}
static class Adapter extends FragmentPagerAdapter {
private final List<Fragment> mFragments = new ArrayList<>();
private final List<String> mFragmentTitles = new ArrayList<>();
public Adapter(FragmentManager fm) {
super(fm);
}
public void addFragment(Fragment fragment, String title) {
mFragments.add(fragment);
mFragmentTitles.add(title);
}
#Override
public Fragment getItem(int position) {
return mFragments.get(position);
}
#Override
public int getCount() {
return mFragments.size();
}
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitles.get(position);
}
}
}
Good day, I have a fragment called MainFragment called from MainActivity. Inside MainFragment I have private OnProgressUpdateListener progressListener; this interface instance helps me talk to ProgressDialog Fragment.
I'm able to initialize interface instance inside my activities but I'm getting ClassCastException when I attempt to initialize the interface instance inside MainFragment
Below are my classes:
--------------------------------------------------------------------------------
Interface
--------------------------------------------------------------------------------
public interface OnProgressUpdateListener
{
void onProgressUpdate(String message);
void onDismissDialog();
}
--------------------------------------------------------------------------------
Child Fragment to MainFragment
--------------------------------------------------------------------------------
public class ProgressbarDialog extends DialogFragment implements OnProgressUpdateListener
{
TextView progressMessage;
ProgressBar progressBar;
View dialogView;
LayoutInflater inflater;
AlertDialog alertDialog;
AlertDialog.Builder dialogBuilder;
public ProgressbarDialog()
{
}
public static ProgressbarDialog newInstance(String title, String message)
{
ProgressbarDialog fragment = new ProgressbarDialog();
Bundle args = new Bundle();
args.putCharSequence("title", title);
args.putCharSequence("message", message);
fragment.setArguments(args);
return fragment;
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState)
{
dialogBuilder = new AlertDialog.Builder(getActivity());
inflater = getActivity().getLayoutInflater();
dialogView = inflater.inflate(R.layout.content_progressdialog,null);
dialogBuilder.setView(dialogView);
progressBar = dialogView.findViewById(R.id.pbProgressSpinner);
progressMessage = dialogView.findViewById(R.id.tvProgressMessage);
dialogBuilder.setTitle(getArguments().getString("title"));
progressBar.setIndeterminate(true);
progressMessage.setText(getArguments().getString("message"));
alertDialog = dialogBuilder.create();
alertDialog.setCanceledOnTouchOutside(false);
alertDialog.show();
return alertDialog;
}
#Override
public void onProgressUpdate(String message)
{
progressMessage.setText(message);
}
#Override
public void onDismissDialog()
{
alertDialog.dismiss();
}
}
--------------------------------------------------------------------------------
MainFragment - Parent Fragment To ProgressbarDialog
--------------------------------------------------------------------------------
public class MainFragment extends Fragment
{
private View mainView;
private CheckBox rememberMe;
private boolean stayLoggedIn;
private CountDownLatch latch;
private FragmentManager manager;
private OnMainListener mListener;
private EditText email, password;
private ProgressbarDialog progressDialog;
private OnProgressUpdateListener progressListener;
private final int REGISTER_CODE = 1, RESET_CODE = 2;
private FloatingActionButton fabRegister, fabLogin, fabReset;
public MainFragment()
{}
public static MainFragment newInstance()
{
MainFragment fragment = new MainFragment();
Bundle args = new Bundle();
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
if (getArguments() != null)
{}
manager = getChildFragmentManager();
progressDialog = ProgressbarDialog.newInstance("Authentication", "Connecting To Server, Please Wait...");
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
// Inflate the layout for this fragment
mainView = inflater.inflate(R.layout.main_fragment, container, false);
stayLoggedIn = false;
rememberMe = mainView.findViewById(R.id.cbRememberMe);
email = mainView.findViewById(R.id.edtLoginEmail);
password = mainView.findViewById(R.id.edtLoginPassword);
fabRegister = mainView.findViewById(R.id.fabRegister);
fabLogin = mainView.findViewById(R.id.fabLogin);
fabReset = mainView.findViewById(R.id.fabReset);
return mainView;
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState)
{
super.onViewCreated(view, savedInstanceState);
email.setTag("Account Email Required!");
password.setTag("Account Password Required!");
}
#Override
public void onStart()
{
super.onStart();
rememberMe.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
stayLoggedIn = b;
}
});
fabRegister.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View view)
{
mListener.onFABInteraction(REGISTER_CODE);
}
});
fabLogin.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view)
{
onLoginRequest();
}
});
fabReset.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view)
{
mListener.onFABInteraction(RESET_CODE);
}
});
}
#Override
public void onAttach(Context context)
{
super.onAttach(context);
try
{
if (context instanceof OnMainListener)
{
mListener = (OnMainListener) context;
}
else
{
throw new RuntimeException(context.toString()
+ " must implement OnMainListener");
}
}
catch (Exception e)
{
Log.e(MainFragment.class.getName(), e.getMessage());
}
}
**#Override
public void onAttachFragment(Fragment childFragment) {
super.onAttachFragment(childFragment);
if(childFragment instanceof OnProgressUpdateListener)
{
progressListener = (OnProgressUpdateListener) childFragment;
//This code is never executed
}
}**
#Override
public void onDetach()
{
super.onDetach();
mListener = null;
}
interface OnMainListener
{
void onLoginSuccess(BackendlessUser user);
void onFABInteraction(int option);
}
private class OnAuthentication extends AsyncTask<String, String, BackendlessUser>
{
#Override
protected void onPreExecute() {
super.onPreExecute();
latch = new CountDownLatch(1);
progressDialog.show(manager, MainFragment.class.getName());
Code Fails here, null pointer exception is thrown because progressListener interface instance is not initialised.
progressListener.onProgressUpdate("Authenticating User, Please Wait...");
}
#Override
protected void onProgressUpdate(String... values)
{
super.onProgressUpdate(values);
progressListener.onProgressUpdate(values[0]);
}
#Override
protected BackendlessUser doInBackground(String... strings)
{
try
{
Backendless.UserService.login(
Utility.getText(email),
Utility.getText(password),
onLoginCallback, stayLoggedIn);
publishProgress("Validating Credentials, Please Wait...");
latch.await();
}
catch (InterruptedException e)
{
publishProgress(e.getMessage());
}
return Utility.loginUser;
}
#Override
protected void onPostExecute(BackendlessUser user)
{
super.onPostExecute(user);
Utility.clearViews(email, password, rememberMe);
progressListener.onDismissDialog();
if(user != null)
{
if(((MainActivity)getActivity()).onRoleValidation(user))
{
mListener.onLoginSuccess(user);
}
else
{
//send a push notification to master channel
Utility.sendNotification(getActivity(),
"New Application User",
"New Registration",
"New User Awaiting Role Assignment", "Master",
"Role Assignment Pending For User :"
+ user.getEmail()
+ ":" + user.getProperty("name").toString()
+ " " + user.getProperty("surname").toString());
}
}
}
}
private void onLoginRequest()
{
if(Utility.hasText(email, password))
{
if(Utility.isEmailValid(Utility.getText(email)))
{
new OnAuthentication().
execute(Utility.getText(email),
Utility.getText(password));
}
else
{
Utility.showToast(getActivity(), "Invalid Email");
Utility.clearViews(email);
}
}
}
private AsyncCallback<BackendlessUser> onLoginCallback = new AsyncCallback<BackendlessUser>()
{
#Override
public void handleResponse(BackendlessUser backendlessUser)
{
latch.countDown();
Utility.loginUser = backendlessUser;
Log.i(MainFragment.class.getName(), "Login Successful!\n" + backendlessUser.getUserId());
}
#Override
public void handleFault(BackendlessFault backendlessFault)
{
latch.countDown();
progressListener.onProgressUpdate("Login Unsuccessful!");
Log.e(MainFragment.class.getName(), "Login Failed!\n" + backendlessFault.getMessage());
}
};
}
I'm developing an android kind-of-gallery-app with Firebase, so I will have plenty of images. I know that I need to be careful about memory management.
When I was searching how to find memory leak in android apps, I came across with LeakCanary. It looks really great, so I used in my app.
Basically my app has 3 fragments, which are Drawer, ProductGrid and ProductDetail. Sometimes LeakCanary says that I have a memory leak in ProductGrid, but I couldn't find it! Usually, adapters or static methods or listeners could cause memory leak because of Context object, but my knowledge is not sufficient to say 'aah that's because of here'
Here are the classes. Where is the leak?(If you suggest me anything that I can improve my code or approach, I would be appreciated!)
Because of body character limit, I put the link leak canary log file.
How I suspect there is a memory leak
First of all, LeakCanary shows a dialog and logs the dump. Second thing is, when I click on an item in drawer, in grid and in detail like 15 times(respectively), memory usage increases. It starts with 18M, increases 22M-23M after showing 3 images(normal). Then it heads up to 29M-30M after clicking on 15 times. If you click on around 30-40, memory usage increases 34M-35M
Edit: I've just figured out that, if I open and close drawer, memory usage increases 0.05M everytime, so one time opening and closing drawer costs 0.1M! What am i missing?
Main.java
public class Main extends ActionBarActivity implements DrawerListener {
private Toolbar mToolbar;
private Drawer drawerFragment;
private HomePage homeFragment;
private FragmentHelper fh = new FragmentHelper();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
if (homeFragment == null)
homeFragment = new HomePage();
if (savedInstanceState == null) {
mToolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(mToolbar);
getSupportActionBar().setDisplayShowHomeEnabled(true);
drawerFragment = (Drawer)
getSupportFragmentManager().findFragmentById(R.id.navigation_drawer);
drawerFragment.setUp(R.id.navigation_drawer,
(DrawerLayout) findViewById(R.id.drawer_layout), mToolbar);
drawerFragment.setDrawerListener(this);
drawerFragment.setRetainInstance(true);
displayView(null);
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_home) {
getSupportActionBar().setTitle(getString(R.string.app_name));
fh.replace(getSupportFragmentManager(), homeFragment, R.id.container_body);
return true;
}
if (id == R.id.action_settings) {
return true;
}
if (id == R.id.action_search) {
Toast.makeText(getApplicationContext(), "Search action is selected!", Toast.LENGTH_SHORT).show();
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onDrawerItemSelected(View view, int position, Category category) {
displayView(category);
}
private void displayView(Category category) {
if (category != null) {
getSupportActionBar().setTitle(category.getName());
ProductGrid gridFragment = new ProductGrid();
Bundle args = new Bundle();
args.putString(Product.CATEGORY_ID, category.getId());
gridFragment.setArguments(args);
fh.replace(getSupportFragmentManager(), gridFragment, R.id.container_body);
} else {
getSupportActionBar().setTitle(getString(R.string.app_name));
fh.replace(getSupportFragmentManager(), homeFragment, R.id.container_body);
}
}
}
Drawer.java
public class Drawer extends Fragment {
private Firebase mFirebase;
private Alert alert;
private RecyclerView recyclerView;
private View containerView;
private DrawerLayout mDrawerLayout;
private ActionBarDrawerToggle mDrawerToggle;
private DrawerListener drawerListener;
private DrawerAdapter mAdapter;
private List<Category> mCategories;
public Drawer() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
alert = new Alert(getActivity().getApplicationContext());
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View layout = inflater.inflate(R.layout.drawer, container, false);
mCategories = new ArrayList<>();
mAdapter = new DrawerAdapter(mCategories);
recyclerView = (RecyclerView) layout.findViewById(R.id.drawer_list);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity().getApplicationContext()));
recyclerView.setItemAnimator(new SlideInOutLeftItemAnimator(recyclerView));
recyclerView.setAdapter(mAdapter);
mFirebase = new Firebase(getActivity().getResources().getString(R.string.firebase_ref))
.child(FirebaseRoots.CATEGORY);
Query query = mFirebase.orderByChild(Category.PRIO);
query.addChildEventListener(new ChildEventListener() {
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
Category model = dataSnapshot.getValue(Category.class);
model.setId(dataSnapshot.getKey());
mCategories.add(model);
recyclerView.scrollToPosition(mCategories.size() - 1);
mAdapter.notifyItemInserted(mCategories.size() - 1);
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
Category model = dataSnapshot.getValue(Category.class);
model.setId(dataSnapshot.getKey());
int index = -1;
for (int i = 0; i < mCategories.size(); i++) {
if (mCategories.get(i).getId().equals(model.getId())) {
index = i;
break;
}
}
mCategories.set(index, model);
recyclerView.scrollToPosition(0);
mAdapter.notifyItemChanged(index);
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
Category model = dataSnapshot.getValue(Category.class);
model.setId(dataSnapshot.getKey());
int index = -1;
for (int i = 0; i < mCategories.size(); i++) {
if (mCategories.get(i).getId().equals(model.getId())) {
index = i;
break;
}
}
mCategories.remove(index);
recyclerView.scrollToPosition(0);
mAdapter.notifyItemRemoved(index);
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(FirebaseError firebaseError) {
alert.show(firebaseError.toString());
}
});
recyclerView.addOnItemTouchListener(new RecyclerTouchListener(getActivity().getApplicationContext(),
recyclerView, new ClickListener() {
#Override
public void onClick(View view, int position) {
Category category = mCategories.get(position);
drawerListener.onDrawerItemSelected(view, position, category);
mDrawerLayout.closeDrawer(containerView);
}
#Override
public void onLongClick(View view, int position) {
}
}));
return layout;
}
public void setUp(int fragmentId, DrawerLayout drawerLayout, final Toolbar toolbar) {
containerView = getActivity().findViewById(fragmentId);
mDrawerLayout = drawerLayout;
mDrawerToggle = new ActionBarDrawerToggle(getActivity(), drawerLayout, toolbar, R.string.drawer_open, R.string.drawer_close) {
#Override
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
getActivity().invalidateOptionsMenu();
}
#Override
public void onDrawerClosed(View drawerView) {
super.onDrawerClosed(drawerView);
getActivity().invalidateOptionsMenu();
}
#Override
public void onDrawerSlide(View drawerView, float slideOffset) {
super.onDrawerSlide(drawerView, slideOffset);
toolbar.setAlpha(1 - slideOffset / 2);
}
};
mDrawerLayout.setDrawerListener(mDrawerToggle);
mDrawerLayout.post(new Runnable() {
#Override
public void run() {
mDrawerToggle.syncState();
}
});
}
public void setDrawerListener(DrawerListener listener) {
this.drawerListener = listener;
}
}
ProductGrid.java
public class ProductGrid extends Fragment implements ChildEventListener{
private Firebase mFirebaseRef;
private Alert alert;
private RecyclerView recyclerView;
private GridAdapter mAdapter;
private String categoryId;
private ArrayList<Product> mProducts;
private FileSystem fs;
public ProductGrid() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.categoryId = getArguments().getString(Product.CATEGORY_ID);
this.alert = new Alert(getActivity().getApplicationContext());
this.fs = new FileSystem(getActivity().getApplicationContext());
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View layout = inflater.inflate(R.layout.grid, container, false);
fieldInitialize(layout);
mProducts = new ArrayList<>();
mAdapter = new GridAdapter(mProducts, getActivity().getApplicationContext());
recyclerView.addItemDecoration(new MarginDecoration(getActivity()));
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new GridLayoutManager(getActivity(), 2));
recyclerView.setAdapter(mAdapter);
mFirebaseRef = new Firebase(getActivity().getResources().getString(R.string.firebase_ref))
.child(FirebaseRoots.PRODUCT);
Query query = mFirebaseRef.orderByChild(Product.CATEGORY_ID).equalTo(categoryId);
query.addChildEventListener(this);
recyclerView.addOnItemTouchListener(new RecyclerTouchListener(getActivity(), recyclerView, new ClickListener() {
#Override
public void onClick(View view, int position) {
ProductDetail detailFragment = new ProductDetail();
Bundle args = new Bundle();
args.putSerializable("product", mProducts);
args.putInt("position", position);
detailFragment.setArguments(args);
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.container_body, detailFragment);
transaction.addToBackStack(null);
transaction.commit();
}
#Override
public void onLongClick(View view, int position) {
}
}));
return layout;
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
}
#Override
public void onDetach() {
super.onDetach();
}
public void fieldInitialize(View layout) {
recyclerView = (RecyclerView) layout.findViewById(R.id.product_grid_layout);
}
#Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
Product model = dataSnapshot.getValue(Product.class);
model.setId(dataSnapshot.getKey());
mProducts.add(model);
if (!fs.getFileNames().contains(model.getName() + FileExt.JPG.get())) {
fs.writeImage(model.getName(), ImageUtil.base64ToBitmap(
StringUtil.getBase64FromUrl(model.getImageData().getDataUrl())));
}
Collections.sort(mProducts);
recyclerView.scrollToPosition(0);
mAdapter.notifyItemInserted(mProducts.size() - 1);
}
#Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
Product model = dataSnapshot.getValue(Product.class);
model.setId(dataSnapshot.getKey());
fs.writeImage(model.getName(), ImageUtil.base64ToBitmap(
StringUtil.getBase64FromUrl(model.getImageData().getDataUrl())));
int index = -1;
for (int i = 0; i < mProducts.size(); i++) {
if (mProducts.get(i).getId().equals(model.getId())) {
index = i;
break;
}
}
mProducts.set(index, model);
recyclerView.scrollToPosition(0);
mAdapter.notifyItemChanged(index);
}
#Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
Product model = dataSnapshot.getValue(Product.class);
model.setId(dataSnapshot.getKey());
fs.deleteImage(model.getName());
int index = -1;
for (int i = 0; i < mProducts.size(); i++) {
if (mProducts.get(i).getId().equals(model.getId())) {
index = i;
break;
}
}
mProducts.remove(index);
recyclerView.scrollToPosition(0);
mAdapter.notifyItemRemoved(index);
}
#Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
#Override
public void onCancelled(FirebaseError firebaseError) {
alert.show(firebaseError.toString());
}
#Override public void onDestroy() {
super.onDestroy();
RefWatcher refWatcher = AcarsanApp.getRefWatcher(getActivity());
refWatcher.watch(this);
}
}
ProductDetail.java
public class ProductDetail extends Fragment {
private FullScreenImageAdapter adapter;
private ViewPager viewPager;
private ArrayList<Product> products;
private int position;
public ProductDetail() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
products = (ArrayList<Product>) getArguments().getSerializable("product");
position = getArguments().getInt("position");
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.product_detail, container, false);
viewPager = (ViewPager) view.findViewById(R.id.product_gallery);
adapter = new FullScreenImageAdapter(getActivity().getApplicationContext(), products);
viewPager.setAdapter(adapter);
viewPager.setCurrentItem(position);
return view;
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
}
#Override
public void onDetach() {
super.onDetach();
}
}
FileSystem
public class FileSystem {
private Context mContext;
public static final String PHOTOS_FOLDER = "photos";
public FileSystem(Context mContext) {
this.mContext = mContext;
}
public void writeImage(String name, Bitmap bitmap) {
String filename = name + FileExt.JPG.get();
File dir = mContext.getDir(PHOTOS_FOLDER, Context.MODE_PRIVATE);
File fileWithinDir = new File(dir, filename);
FileOutputStream outputStream;
try {
outputStream = new FileOutputStream(fileWithinDir);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public List<String> getFileNames() {
List<String> fileNames = new ArrayList<>();
File file = mContext.getDir(PHOTOS_FOLDER, Context.MODE_PRIVATE);
File[] files = file.listFiles();
for (File f : files) {
fileNames.add(f.getName());
}
return fileNames;
}
}
ImageUtil
public class ImageUtil {
public static Bitmap base64ToBitmap(String encodedImage) {
if (encodedImage == null)
return null;
byte[] decodedString = Base64.decode(encodedImage, Base64.DEFAULT);
return BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);
}
}