I've created a RecyclerView in Android Studio like in an other fragment. The problem is that all is working for the first look but after creating a row object and stating the app I can't see any entries. I've did this RecyclerView the the same way as my old one which works great.. I've searched a lot but I can find the error.
This is my fragment xml:
<android.support.v4.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/training_swiperefresh"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/trainingtTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:layout_marginTop="0dp"
android:layout_marginBottom="16dp"
android:textStyle="bold"
android:textColor="#color/colorPrimary"
android:text="#string/trainingTitle" />
<android.support.v7.widget.RecyclerView
android:id="#+id/training_recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="vertical"
android:layout_below="#+id/trainingtTitle" />
</RelativeLayout>
</android.support.v4.widget.SwipeRefreshLayout>
This is the row-layout for the RecyclerView:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:focusable="true"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:clickable="true"
android:background="?android:attr/selectableItemBackground"
android:orientation="vertical">
<!-- Plan icon -->
<ImageView
android:id="#+id/planImage"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_centerVertical="true"
android:layout_alignParentStart="true"
android:layout_marginRight="8dp"
android:layout_marginTop="1dp"
android:layout_marginBottom="1dp"
android:contentDescription="Icon"
android:src="#drawable/ic_menu_train" />
<!-- Plan title -->
<TextView
android:id="#+id/planTitle"
android:textColor="#color/colorBlack"
android:layout_width="match_parent"
android:layout_marginLeft="40dp"
android:layout_marginRight="40dp"
android:layout_marginTop="14dp"
android:textSize="16dp"
android:layout_height="wrap_content" />
<!-- Plan type -->
<TextView
android:id="#+id/planType"
android:layout_below="#id/planTitle"
android:layout_marginLeft="40dp"
android:layout_marginRight="40dp"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<!-- Plan date -->
<TextView
android:id="#+id/planDate"
android:layout_width="match_parent"
android:layout_below="#id/planType"
android:layout_marginLeft="42dp"
android:layout_marginRight="40dp"
android:layout_marginBottom="14dp"
android:layout_height="wrap_content" />
<!-- Plan view -->
<ImageView
android:id="#+id/planView"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_marginTop="1dp"
android:layout_marginBottom="1dp"
android:contentDescription="Icon"
android:src="#drawable/ic_menu_show" />
<View
android:layout_width="fill_parent"
android:layout_height="1dip"
android:layout_below="#id/planDate"
android:layout_marginLeft="42dp"
android:background="#DCDCDC" />
</RelativeLayout>
This is my Fragment where I call the Adapter:
public class TrainingFragment extends Fragment {
private OnFragmentInteractionListener mListener;
// Variables for Recycler View
private List<Plans> planList = new ArrayList<>();
private RecyclerView trainingRecyclerView;
private PlansAdapter pAdapter;
public TrainingFragment() {
// Required empty public constructor
}
//Change the title in action bar
public void onResume() {
super.onResume();
String titleString = getResources().getString(R.string.title_activity_navigation_drawer_training);
// Set title bar
((NavigationDrawerActivity) getActivity())
.setActionBarTitle(titleString);
}
public static TrainingFragment newInstance() {
TrainingFragment fragment = new TrainingFragment();
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Menü bekannt geben, dadurch kann Fragment Menü-Events verarbeiten
setHasOptionsMenu(true);
}
//Fragment XML geben, sowie als Menü setzen
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu_training, menu);
// Declare ImageView and Animation for rotation animation
MenuItem reloadButton = (MenuItem) menu.findItem(R.id.menu_reloadbutton);
final Animation rotation = AnimationUtils.loadAnimation(getActivity(), R.anim.animation_rotate);
//if (reloadButton != null) {
// //reloadButton.setImageResource(R.drawable.ic_menu_reloadentry);
// reloadButton.getActionView().setOnClickListener(new View.OnClickListener() {
// #Override
// public void onClick(View view) {
// rotation.setRepeatCount(Animation.INFINITE);
// view.startAnimation(rotation);
// }
// });
//}
}
//AddEntry click abfangen und verarbeiten
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Wir prüfen, ob Menü-Element mit der ID "action_daten_aktualisieren"
// ausgewählt wurde und geben eine Meldung aus
int id = item.getItemId();
if (id == R.id.menu_reloadbutton) {
// Text ausgeben
//Toast.makeText(getActivity(), "Liste aktualisieren gedrückt!", Toast.LENGTH_LONG).show();
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_training, container, false);
// Get Refresh Layout
SwipeRefreshLayout swipeRefreshLayout = (SwipeRefreshLayout) view.findViewById(R.id.training_swiperefresh);
// Change color for the refresh layout
swipeRefreshLayout.setColorSchemeColors(Color.rgb(99, 195, 195));
trainingRecyclerView = (RecyclerView) view.findViewById(R.id.training_recycler_view);
pAdapter = new PlansAdapter(planList, getContext());
RecyclerView.LayoutManager pLayoutManager = new LinearLayoutManager(getActivity().getApplicationContext());
trainingRecyclerView.setLayoutManager(pLayoutManager);
trainingRecyclerView.setItemAnimator(new DefaultItemAnimator());
trainingRecyclerView.setAdapter(pAdapter);
preparePlansData();
return view;
}
private void preparePlansData() {
// Set plan data
Plans plan = new Plans("ABC-Bestellung", "Muskelaufbau", "Datum: 21.04.1997");
// Add Object to list
planList.add(plan);
plan = new Plans("test", "tttt", "ttttt");
planList.add(plan);
// Notify data changes
pAdapter.notifyDataSetChanged();
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
}
#Override
public void onStart() {
super.onStart();
try {
mListener = (OnFragmentInteractionListener) getActivity();
} catch (ClassCastException e) {
throw new ClassCastException(getActivity().toString()
+ " must implement OnFragmentInteractionListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
}
This is my Adapter:
public class PlansAdapter extends RecyclerView.Adapter<PlansAdapter.MyPlanHolder> {
private List<Plans> planList;
private final Context customContext;
public class MyPlanHolder extends RecyclerView.ViewHolder {
public TextView planTitle, planType, planDate;
public MyPlanHolder(View view) {
super(view);
planTitle = (TextView) view.findViewById(R.id.planTitle);
planType = (TextView) view.findViewById(R.id.planType);
planDate = (TextView) view.findViewById(R.id.planDate);
}
}
public PlansAdapter(List<Plans> planList, Context customContext) {
this.planList = planList;
this.customContext = customContext;
}
#Override
public MyPlanHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.plans_list_row, parent, false);
return new MyPlanHolder(itemView);
}
#Override
public void onBindViewHolder(MyPlanHolder holder, int position) {
final Plans plan = planList.get(position);
holder.planTitle.setText(plan.getPlanTitle());
holder.planType.setText(plan.getPlanType());
holder.planDate.setText(plan.getPlanDate());
}
#Override
public int getItemCount() {
return 0;
}
}
And finaly my object class for the elements:
public class Plans {
private String planTitle, planType, planDate;
public Plans(String planTitle, String planType, String planDate) {
this.planTitle = planTitle;
this.planType = planType;
this.planDate = planDate;
}
public void setPlanTitle(String planTitle) {
this.planTitle = planTitle;
}
public String getPlanTitle() {
return planTitle;
}
public void setPlanType(String planType) {
this.planType = planType;
}
public String getPlanType() {
return planType;
}
public void setPlanDate(String planDate) {
this.planDate = planDate;
}
public String getPlanDate() {
return planDate;
}
}
I hope that you can find the issue.
Inside Adapter's getItemCount() method you are returning 0 as size of list.You should change it as return planList.size()
Your code is fine except in your adapter you are returning 0 in getItemCount() method.
Here's the updated code :
public class PlansAdapter extends RecyclerView.Adapter<PlansAdapter.MyPlanHolder> {
private List<Plans> planList;
private final Context customContext;
public class MyPlanHolder extends RecyclerView.ViewHolder {
public TextView planTitle, planType, planDate;
public MyPlanHolder(View view) {
super(view);
planTitle = (TextView) view.findViewById(R.id.planTitle);
planType = (TextView) view.findViewById(R.id.planType);
planDate = (TextView) view.findViewById(R.id.planDate);
}
}
public PlansAdapter(List<Plans> planList, Context customContext) {
this.planList = planList;
this.customContext = customContext;
}
#Override
public MyPlanHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.plans_list_row, parent, false);
return new MyPlanHolder(itemView);
}
#Override
public void onBindViewHolder(MyPlanHolder holder, int position) {
final Plans plan = planList.get(position);
holder.planTitle.setText(plan.getPlanTitle());
holder.planType.setText(plan.getPlanType());
holder.planDate.setText(plan.getPlanDate());
}
#Override
public int getItemCount() {
return planList.size();
}
}
Related
I'm relatively new to Android Studio and I'm doing an app, one of it's interface's function is to show the data of various user's and I saw various tutorials on how to list data using FirebaseRecyclerAdapter but they are not working. And now I'm trying to do fragments which I don't know how to do yet.
I'd like to know if this code is properly set up to do a fragment.
My MainActivity.java
public class MainActivity extends AppCompatActivity {
private RelativeLayout pills_layout, appoint_layout, add_pills_layout, add_appoints_layout, account_layout, add_button;
private TextView AccountName0, AccountAge0;
private RecyclerView recyclerView;
private LinearLayoutManager linearLayoutManager;
private FirebaseRecyclerAdapter adapter;
private View view;
private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
= new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.navigation_home:
Home();
return true;
case R.id.navigation_pills:
Pills();
return true;
case R.id.navigation_appointment:
Appointment();
return true;
case R.id.navigation_account:
Account();
return true;
}
return false;
}
};
public MainActivity() {
}
private void Account(){
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) add_button.getLayoutParams();
params.addRule(RelativeLayout.BELOW, R.id.account);
pills_layout.setVisibility(View.GONE);
appoint_layout.setVisibility(View.GONE);
add_pills_layout.setVisibility(View.GONE);
add_appoints_layout.setVisibility(View.GONE);
//account_layout.setVisibility(View.VISIBLE);
add_button.setVisibility(View.VISIBLE);
/*Button accountChangePass = findViewById(R.id.AccountChangePass);
accountChangePass.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent ChangePW = new Intent(MainActivity.this, ChangePW.class);
startActivity(ChangePW);
}
});*/
}
private void Appointment() {
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) add_button.getLayoutParams();
params.addRule(RelativeLayout.BELOW, R.id.add_appoints);
pills_layout.setVisibility(View.GONE);
appoint_layout.setVisibility(View.GONE);
add_pills_layout.setVisibility(View.GONE);
add_appoints_layout.setVisibility(View.VISIBLE);
//account_layout.setVisibility(View.GONE);
add_button.setVisibility(View.VISIBLE);
}
private void Pills() {
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) add_button.getLayoutParams();
params.addRule(RelativeLayout.BELOW, R.id.add_pills);
pills_layout.setVisibility(View.GONE);
appoint_layout.setVisibility(View.GONE);
add_pills_layout.setVisibility(View.VISIBLE);
add_appoints_layout.setVisibility(View.GONE);
//account_layout.setVisibility(View.GONE);
add_button.setVisibility(View.VISIBLE);
}
private void Home() {
pills_layout.setVisibility(View.VISIBLE);
appoint_layout.setVisibility(View.VISIBLE);
add_pills_layout.setVisibility(View.GONE);
add_appoints_layout.setVisibility(View.GONE);
//account_layout.setVisibility(View.GONE);
add_button.setVisibility(View.GONE);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
if (user == null) {
Intent VerifyLogin = new Intent(MainActivity.this, Launcher.class);
VerifyLogin.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(VerifyLogin);
}
pills_layout = findViewById(R.id.pills_layout);
appoint_layout = findViewById(R.id.appoint_layout);
add_pills_layout = findViewById(R.id.add_pills);
add_appoints_layout = findViewById(R.id.add_appoints);
//account_layout = findViewById(R.id.accountlist);
AccountName0 = findViewById(R.id.AccountName0);
AccountAge0 = findViewById(R.id.AccountAge0);
add_button = findViewById(R.id.add);
pills_layout.setVisibility(View.VISIBLE);
appoint_layout.setVisibility(View.VISIBLE);
add_pills_layout.setVisibility(View.GONE);
add_appoints_layout.setVisibility(View.GONE);
//account_layout.setVisibility(View.GONE);
add_button.setVisibility(View.GONE);
recyclerView = findViewById(R.id.accountlist);
linearLayoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(linearLayoutManager);
recyclerView.setHasFixedSize(true);
BottomNavigationView navigation = findViewById(R.id.navigation);
navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
}
public class ViewHolder extends RecyclerView.ViewHolder {
public RelativeLayout root;
public TextView txtTitle;
public TextView txtDesc;
public ViewHolder(View itemView) {
super(itemView);
root = itemView.findViewById(R.id.account);
txtTitle = itemView.findViewById(R.id.AccountName0);
txtDesc = itemView.findViewById(R.id.AccountAge0);
}
public void setTxtTitle(String string) {
txtTitle.setText(string);
}
public void setTxtDesc(String string) {
txtDesc.setText(string);
}
}
#Override
protected void onStart() {
super.onStart();
Query query = FirebaseDatabase.getInstance()
.getReference()
.child("Users");
FirebaseRecyclerOptions<Account> options =
new FirebaseRecyclerOptions.Builder<Account>()
.setQuery(query, new SnapshotParser<Account>() {
#NonNull
#Override
public Account parseSnapshot(#NonNull DataSnapshot snapshot) {
return new Account(snapshot.child("name").getValue().toString(),
snapshot.child("idade").getValue().toString());
}
})
.build();
adapter = new FirebaseRecyclerAdapter<Account, ViewHolder>(options) {
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.account, parent, false);
return new ViewHolder(view);
}
#Override
protected void onBindViewHolder(ViewHolder holder, final int position, Account model) {
holder.setTxtTitle(model.getName());
holder.setTxtDesc(model.getIdade());
holder.root.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(MainActivity.this, String.valueOf(position), Toast.LENGTH_SHORT).show();
}
});
}
};
recyclerView.setAdapter(adapter);
adapter.startListening();
}
#Override
protected void onStop() {
super.onStop();
Query query = FirebaseDatabase.getInstance()
.getReference()
.child("Users");
FirebaseRecyclerOptions<Account> options =
new FirebaseRecyclerOptions.Builder<Account>()
.setQuery(query, new SnapshotParser<Account>() {
#NonNull
#Override
public Account parseSnapshot(#NonNull DataSnapshot snapshot) {
return new Account(snapshot.child("name").getValue().toString(),
snapshot.child("idade").getValue().toString());
}
})
.build();
adapter = new FirebaseRecyclerAdapter<Account, ViewHolder>(options) {
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.account, parent, false);
return new ViewHolder(view);
}
#Override
protected void onBindViewHolder(ViewHolder holder, final int position, Account model) {
holder.setTxtTitle(model.getName());
holder.setTxtDesc(model.getIdade());
holder.root.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(MainActivity.this, String.valueOf(position), Toast.LENGTH_SHORT).show();
}
});
}
};
recyclerView.setAdapter(adapter);
adapter.stopListening();
}
};
My Account.java
public class Account {
private String name, idade;
public Account() {
}
public Account(String name, String idade) {
this.name = name;
this.idade = idade;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getIdade() {
return idade;
}
public void setIdade(String idade) {
this.idade = idade;
}
}
My account.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/account">
<RelativeLayout
android:id="#+id/AccountUser"
android:layout_width="match_parent"
android:layout_height="163dp"
android:layout_marginStart="15dp"
android:layout_marginLeft="15dp"
android:layout_marginTop="15dp"
android:layout_marginEnd="15dp"
android:layout_marginRight="15dp"
android:layout_marginBottom="15dp"
android:background="#drawable/edit_bg"
android:padding="15dp">
<RelativeLayout
android:id="#+id/AccountImage"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/ic_user"/>
</RelativeLayout>
<RelativeLayout
android:id="#+id/AccountInfos"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/AccountImage"
android:layout_toEndOf="#id/AccountImage"
android:layout_marginStart="15dp"
android:layout_marginLeft="15dp">
<TextView
android:id="#+id/AccountName0"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:text="Nome1"
android:textColor="#color/colorWhite"
android:textSize="20sp"
android:textStyle="bold" />
<TextView
android:id="#+id/AccountAge0"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/AccountName0"
android:paddingTop="5dp"
android:paddingBottom="5dp"
android:text="Idade1"
android:textColor="#color/colorWhite"
android:textSize="20sp"
android:textStyle="bold" />
<Button
android:id="#+id/AccountChangePass"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/AccountAge0"
android:text="Mudar Palavra-Passe"
android:textColor="#color/colorWhite"
android:textSize="18sp"
android:textStyle="bold"
android:textAllCaps="false"
android:padding="10dp"
android:layout_marginTop="10dp"
android:background="#drawable/custom_button"/>
</RelativeLayout>
</RelativeLayout>
</RelativeLayout>
</RelativeLayout>
the best way to do that in my opinion is using Fragments.
Create 3 fragments:
Just check the checkBox that says " Create layout XML? "
Create a java class and add this code after create 3 fragments:
public class /* class name 1 */ extends FragmentPagerAdapter {
public /* class name 1 */ (FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position){
case 0:
Fragment1 fragment1= new Fragment1 ();
return fragment1;
case 1:
Fragment2 fragment2 = new Fragment2();
return fragment2 ;
case 2:
Fragment3 fragment3 = new Fragment3 ();
return fragment3 ;
default:
return null;
}
}
#Override
public int getCount() {
return 3;
}
public CharSequence getPageTitle(int position){
switch (position){
case 0:
return "/* set a name to fragment1*/";
case 1:
return "/* set a name to fragment2*/";
case 2:
return "/* set a name to fragment3*/";
default:
return null;
}
}
}
Now in your mainActivity.java add this code:
public class MainActivity extends AppCompatActivity {
private ViewPager mViewPager;
private /* class name 1 */ mSectionsPagerAdapter;
private TabLayout mTabLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mViewPager = findViewById(R.id.main_tabPager);
mSectionsPagerAdapter = new /* class name 1 */(getSupportFragmentManager());
mViewPager.setAdapter(mSectionsPagerAdapter);
mTabLayout = findViewById(R.id.main_tabs);
mTabLayout.setupWithViewPager(mViewPager);
}
}
Now in your mainactivity.xml add this:
<android.support.v4.view.ViewPager
android:id="#+id/main_tabPager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:visibility="visible"
tools:ignore="UnknownId"></android.support.v4.view.ViewPager>
<android.support.design.widget.TabLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/colorAccent"
android:id="#+id/main_tabs">
</android.support.design.widget.TabLayout>
The final result will look like this:
I suppose pills_layout, appoint_layout, .. are your fragment layouts.
Maintaining them by changing their VISIBILITY property is not a good idea.
You have to use the supportFragmentManager instead.
Create a loadFragment method like this
public final boolean loadFragment(#NotNull Fragment fragment) {
this.getSupportFragmentManager().beginTransaction()
.replace(<<id of your fragment container layout>>, fragment, "fragment").commit();
return true;
}
And change your onNavigationItemSelected method to this:
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.navigation_home:
return loadFragment(new HomeFragment());
case R.id.navigation_pills:
return loadFragment(new PillsFragment());
case R.id.navigation_appointment:
return loadFragment(new AppointmentFragment());
case R.id.navigation_account:
return loadFragment(new AccountFragment());
}
return false;
}
};
Now make a seperate class for each fragment and inflate the layout of the right fragment.
here is an example of how your HomeFragment-class has to look like this:
public final class HomeFragment extends Fragment {
#Override
public View onCreate(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
return inflater.inflate(R.layout.<<your homefragment layout name>>, null);
}
}
I hope it's enough to help you out. I'm sorry if there are little mistakes in syntax, I'm used to code Android in Kotlin. But you will get the idea behind it.
I have a recycleView (see picture). You see there are 2 buttons too. Here's the layout file.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="80dp"
android:background="#color/white">
<de.hdodenhof.circleimageview.CircleImageView
android:layout_marginLeft="10dp"
android:id="#+id/main_picture"
android:layout_width="45dp"
android:layout_height="50dp"
android:src="#drawable/pfl_img"
android:layout_centerVertical="true"
android:layout_alignParentStart="true" />
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_toRightOf="#id/main_picture"
android:layout_marginRight="5dp"
android:layout_marginLeft="10dp"
android:id="#+id/relativeLayout2">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Edem Palonik"
android:textSize="17sp"
android:id="#+id/textName"
android:textColor="#color/black"
android:layout_above="#+id/textDescription"
android:layout_alignParentStart="true" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Profession and ..."
android:textColor="#color/black"
android:textSize="17sp"
android:id="#+id/textDescription"
android:layout_centerVertical="true"
android:layout_alignParentStart="true" />
<ImageView
android:layout_width="20dp"
android:layout_height="18dp"
android:layout_marginTop="2dp"
android:layout_below="#+id/textDescription"
android:id="#+id/historyIcon"
android:layout_alignParentStart="true" />
<TextView
android:layout_marginLeft="5dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/date"
android:textSize="14sp"
android:text="17/12/2017/13:46"
android:layout_marginTop="2dp"
android:layout_below="#+id/textDescription"
android:layout_toEndOf="#+id/historyIcon" />
</RelativeLayout>
<Button
android:id="#+id/call_button"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_marginRight="10dp"
android:background="#drawable/call_img"
android:layout_centerVertical="true"
android:layout_toStartOf="#+id/sms_button" />
<Button
android:id="#+id/sms_button"
android:layout_width="37dp"
android:layout_height="32dp"
android:background="#drawable/sms_img"
android:layout_alignTop="#+id/call_button"
android:layout_alignParentEnd="true" />
<View
android:layout_width="match_parent"
android:layout_height="0.8dp"
android:layout_alignParentBottom="true"
android:background="#color/gray" />
I know, I can use recyclerViewItemCLickListener, but I wanna click on last 2 buttons separately, so what do I need to do?
So I wanna click on last buttons separately, without clicking all line, I want only last buttons to be clickable.
Here's the java code.
public class ConnectionsFragment extends Fragment {
private View mainView;
private RecyclerView recyclerView;
private List<Connections_item> list;
private Button call, sms;
public ConnectionsFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mainView = inflater.inflate(R.layout.connections_fragment, container, false);
recyclerView = (RecyclerView) mainView.findViewById(R.id.recycler_connection);
ConnectionsAdapter adapter = new ConnectionsAdapter(getActivity(), list);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
recyclerView.setAdapter(adapter);
init(mainView);
return mainView;
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
list = new ArrayList<>();
list.add(new Connections_item(R.drawable.pfl_img, "Anun Azganun1", "Inch vor text", R.drawable.missed, "23/11/1998 00:00"));
list.add(new Connections_item(R.drawable.pfl_img, "Anun Azganun2", "Inch vor text", R.drawable.callagain, "24/11/1998 01:00"));
list.add(new Connections_item(R.drawable.pfl_img, "Anun Azganun3", "Inch vor text", R.drawable.missed, "25/11/1998 02:00"));
public void init(View v) {
call = (Button) v.findViewById(R.id.call_button);
sms = (Button) v.findViewById(R.id.sms_button);
// call.setOnClickListener(new View.OnClickListener() {
// #Override
// public void onClick(View view) {
// Toast.makeText(getActivity(), "Whom you wanna call?", Toast.LENGTH_SHORT).show();
// }
// });
// sms.setOnClickListener(new View.OnClickListener() {
// #Override
// public void onClick(View view) {
// Toast.makeText(getActivity(), "Whom you wanna send sms?", Toast.LENGTH_SHORT).show();
// }
// });
}
}
Here's the adapter code.
public class ConnectionsAdapter extends RecyclerView.Adapter<ConnectionsAdapter.MyViewHolder> {
Context context;
List<Connections_item> list = new ArrayList<>();
public ConnectionsAdapter(Context context, List<Connections_item> list) {
this.context = context;
this.list = list;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v;
v = LayoutInflater.from(context).inflate(R.layout.connections_view_item, parent, false);
MyViewHolder holder = new MyViewHolder(v);
return holder;
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
holder.mainImage.setImageResource(list.get(position).getMainImage());
holder.fullName.setText(list.get(position).getFullName());
holder.description.setText(list.get(position).getDescription());
holder.historyImage.setImageResource(list.get(position).getHistoryIcon());
holder.date.setText(list.get(position).getDate());
}
#Override
public int getItemCount() {
return list.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder {
ImageView mainImage, historyImage;
TextView fullName, description, date;
Button call, sms;
public MyViewHolder(View v) {
super(v);
mainImage = (ImageView) v.findViewById(R.id.main_picture);
historyImage = (ImageView) v.findViewById(R.id.historyIcon);
fullName = (TextView) v.findViewById(R.id.textName);
description = (TextView) v.findViewById(R.id.textDescription);
date = (TextView) v.findViewById(R.id.date);
call = (Button) v.findViewById(R.id.call_button);
sms = (Button) v.findViewById(R.id.sms_button);
}
}
}
Using interface you can achieve this
public class TestAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
Context mContext;
ArrayList<Data> mData;
OnButtonClickListeners onButtonClickListeners;
public TestAdapter(Context mContext, ArrayList<String> mData) {
this.mContext = mContext;
this.mData = mData;
}
public void setOnButtonClickListeners(OnButtonClickListeners listener){
this.onButtonClickListeners = listener;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
MyViewHolder vh;
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_layout, parent, false);
vh = new MyViewHolder(v);
return vh;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
//Bind holder here
}
#Override
public int getItemCount() {
return mData.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
#Bind(R.id.call_button)
Button btnCall;
#Bind(R.id.sms_button)
Button btnSms;
public MyViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
btnCall.setOnClickListener(this);
btnSms.setOnClickListener(this);
}
#Override
public void onClick(View v) {
if(this.onButtonClickListeners!=null){
switch (v.getId()) {
case R.id.call_button:
onButtonClickListeners.onCallClick(getAdapterPosition());
break;
case R.id.sms_button:
onButtonClickListeners.onSmsClick(getAdapterPosition());
break;
}
}
}
}
public interface OnButtonClickListeners{
void onCallClick(int position);
void onSmsClick(int position);
}
}
Then After you can use the call to this interface from Activity and Fragment like below
private void setUpRecyclerView(){
mAdapter = new ProfileAdapter(mContext,new ArrayList<String>());
lm = new LinearLayoutManager(getActivity());
rvFeeds.setLayoutManager(lm);
rvFeeds.setAdapter(mAdapter);
mAdapter.setOnButtonClickListeners(new OnButtonClickListeners() {
#Override
public void onCallClick(int position) {
//To do your code here
}
#Override
public void onSmsClick(int position) {
//To do your code here
}
})
}
As adapter holds the recyclerView item and buttons are in the item
so all code related to button will be in the adapter only.
In adapter modify the code :
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
holder.mainImage.setImageResource(list.get(position).getMainImage());
holder.fullName.setText(list.get(position).getFullName());
holder.description.setText(list.get(position).getDescription());
holder.historyImage.setImageResource(list.get(position).getHistoryIcon());
holder.date.setText(list.get(position).getDate());
holder.call.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(getActivity(), "Whom you wanna call?", Toast.LENGTH_SHORT).show();
}
});
holder.sms.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(getActivity(), "Whom you wanna send sms?", }
});
}
In java file just remove call and sms button initialization and listners.
You can try to implement onClickListener to the buttons when you are creating the view in the ViewHolder for the recycler view. Then pass an interface with two methods for two buttons and implement the interface in where ever you require.
Like the example:
public class MyViewHolder extends RecyclerView.ViewHolder {
public MyViewHolder(View itemView, ButtonClickListener listner) {
super(itemView);
Button b1 = itemView.findViewById(...);
Button b2 = itemView.findViewById(...);
b1.setOnClickListener(view -> listener.onButton1Click());
b2.setOnClickListener(view -> listener.onButton2Click());
}
}
And now the interface
public interface ButtonClickListener {
void onButton1Click();
void onButton2Click();
}
Otherwise, if you are accustomed with bus you can use instead of using interface. It will make the code much cleaner.
I have a recyclerview which shows multiple cardviews with items. In the recyclerview, I have a popup menu to delete that current cardview.
When the dataset is empty I would like to show an empty view. Something with an image and text saying "empty" I have tried some online examples. No success.
My layout is a cardview(card_view_row.xml) is a simple view with a cardview that shows a few items.
Here is my recyclerview
public class AlarmRecyclerViewAdapter extends
RecyclerView.Adapter<AlarmRecyclerViewAdapter.DataObjectHolder> {
private ArrayList<Alarm> mDataset;
private static AlarmRecyclerViewAdapter.MyClickListener myClickListener;
private AlarmDataAccess dataAccess;
private Alarm alarm;
private int switchOn = 1;
private int switchOff = 0;
private static Context context;
private PopupMenu popupMenu;
public static class DataObjectHolder extends RecyclerView.ViewHolder
implements View
.OnClickListener {
TextView label;
TextView dateTime;
TextView label2;
TextView textViewLabel;
TextView gender;
TextView daysofweek;
Switch aSwitch;
ImageView trash;
public DataObjectHolder(View itemView) {
super(itemView);
dateTime = (TextView) itemView.findViewById(R.id.textView2);
label = (TextView) itemView.findViewById(R.id.textView);
label2 =(TextView) itemView.findViewById(R.id.textView3);
aSwitch = (Switch)itemView.findViewById(R.id.switchButton);
trash = (ImageView)itemView.findViewById(R.id.imageTrash);
gender = (TextView)itemView.findViewById(R.id.textViewGender);
daysofweek = (TextView)itemView.findViewById(R.id.textViewDays);
textViewLabel = (TextView)itemView.findViewById(R.id.textViewLabel);
itemView.setOnClickListener(this);
}
#Override
public void onClick(View v) {
myClickListener.onItemClick(getAdapterPosition(), v);
}
}
public void setOnItemClickListener(AlarmRecyclerViewAdapter.MyClickListener myClickListener) {
this.myClickListener = myClickListener;
}
public AlarmRecyclerViewAdapter(ArrayList<Alarm> myDataset, Context context2) {
mDataset = myDataset;
context = context2;
}
#Override
public AlarmRecyclerViewAdapter.DataObjectHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.card_view_row, parent, false);
AlarmRecyclerViewAdapter.DataObjectHolder dataObjectHolder = new AlarmRecyclerViewAdapter.DataObjectHolder(view);
return dataObjectHolder;
}
#Override
public void onBindViewHolder(final AlarmRecyclerViewAdapter.DataObjectHolder holder, final int position) {
boolean status = false;
int gender;
alarm = new Alarm();
dataAccess = new AlarmDataAccess(context);
dataAccess.open();
holder.label.setText(mDataset.get(position).getHourOfDay() + ":" + mDataset.get(position).getMinute() + " " + mDataset.get(position).getTimeSet());
holder.textViewLabel.setText(mDataset.get(position).getLabel());
gender = mDataset.get(position).getGender();
if(gender == 0){
holder.gender.setText("Male voice");
}else{
holder.gender.setText("Female voice");
}
holder.daysofweek.setText(mDataset.get(position).getDays());
holder.label2.setText("" + mDataset.get(position).getAffirmationName());
holder.trash.setImageResource(R.drawable.menu2);
if( mDataset.get(position).getStatus() == 0){
status = false;
}else {
status = true;
}
holder.aSwitch.setChecked(status);
holder.aSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (buttonView.isPressed()) {
if (isChecked) {
mDataset.get(position).setStatus(switchOn);
} else {
mDataset.get(position).setStatus(switchOff);
}
alarm.setId(mDataset.get(position).getId());
alarm.setStatus(mDataset.get(position).getStatus());
dataAccess.updateStatus(alarm);
}
}
});
holder.trash.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
popupMenu = new PopupMenu(AlarmRecyclerViewAdapter.context, v);
popupMenu.inflate(R.menu.popup_menu);
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.edit:
long selectedAlarmId = mDataset.get(position).getId();
Intent intent = new Intent(AlarmRecyclerViewAdapter.context, EditAlarmActivity.class);
intent.putExtra("id", selectedAlarmId);
intent.putExtra("Edit", "FromEdit");
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_NEW_TASK);
AlarmRecyclerViewAdapter.context.startActivity(intent);
return true;
case R.id.delete:
long id = mDataset.get(position).getId();
mDataset.remove(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, mDataset.size());
dataAccess.deleteAlarm(id);
return true;
}
return false;
}
});
popupMenu.show();
}
});
}
public void deleteItem(int index) {
mDataset.remove(index);
notifyItemRemoved(index);
}
#Override
public int getItemCount() {
return mDataset.size();
}
}
My recyclerview is inside a fragment view
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/fragment_place">
<ImageButton
android:id="#+id/add_button"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_gravity="end|bottom"
android:tint="#color/icon"
android:elevation="12dp"
android:background="#drawable/oval_ripple"
tools:backgroundTint="#96ceb4"
android:src="#android:drawable/ic_input_add"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true"
android:layout_marginStart="12dp"
android:layout_marginTop="14dp" />
<android.support.v7.widget.RecyclerView
android:id="#+id/my_recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="vertical"
android:layout_below="#+id/add_button"
android:layout_centerHorizontal="true"
android:layout_marginTop="16dp" />
</RelativeLayout>
Is there a way to detect if the data set is empty to show an empty view with text saying empty or something? I need this done inside recyclerview since I am deleting items inside there.
EDIT
I finally figured out how to do it. I am posting this incase anyone else has the same problem.
http://akbaribrahim.com/empty-view-for-androids-recyclerview/
For my personal use I use this trick :
I use two LinearLayout, one with my RecyclerView and another with a simple TextView saying "Empty". Both are in the same parent view.
<LinearLayout
android:id="#+id/linearContent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:visibility="invisible">
<android.support.v7.widget.RecyclerView
android:id="#+id/my_recycler_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:scrollbars="vertical" />
</LinearLayout>
<LinearLayout
android:id="#+id/linearEmpty"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="#+id/textEmpty"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="30dp"
android:text="#string/dialog_no_result"
android:textColor="#color/cardview_dark_background" />
</LinearLayout>
And when I update my list of item I call this method :
if (linearContent != null && linearEmpty != null) {
if (mListItems.isEmpty()) {
linearContent.setVisibility(View.GONE);
linearEmpty.setVisibility(View.VISIBLE);
textEmpty.setVisibility(View.VISIBLE);
} else {
linearContent.setVisibility(View.VISIBLE);
linearEmpty.setVisibility(View.GONE);
textEmpty.setVisibility(View.GONE);
}
}
Then I use the same layout, but just change the visibility of some objects.
Hope it help.
I have an app I am writing and it is already contains a lot of code, I decided I want to add a navigation drawer to the main activity toolbar but I don't know how to do it without creating a new navigation drawer project and copy my whole project to it which seems like a lot of work, is there a tutorial to add a navigation drawer to an existing project?
Create a layout layout_left_menu.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/bgLeftMenu">
<ImageView android:id="#+id/header"
android:src="#drawable/ic_launcher"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_marginTop="26dp"
android:layout_marginBottom="8dp"
android:layout_marginLeft="30dp"
android:layout_marginStart="40dp"/>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="48dp"
android:layout_marginTop="26dp"
android:layout_marginLeft="10dp"
android:layout_toRightOf="#id/header">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_centerInParent="true">
<TextView
android:id="#+id/userName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/app_name"
android:textColor="#color/pressed"/>
<TextView
android:id="#+id/userEmail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/app_name"
android:layout_below="#id/userName"
android:layout_centerInParent="true"
android:textColor="#color/pressed"
android:visibility="gone"/>
</LinearLayout>
</RelativeLayout>
<ListView android:id="#+id/menu_items_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/header"
android:dividerHeight="0dp"
android:divider="#null"
android:background="#color/bgLeftMenu"/>
<ProgressBar android:id="#+id/progress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:visibility="gone"/>
</RelativeLayout>
Inflate it in a Custom View:
public class SimpleLeftMenuView extends NavigationView {
private LayoutInflater mInflater;
private Context mContext;
private ListView mItemsList;
private MenuItemsAdapter mItemsAdapter;
private ProgressBar mProgress;
private OnClickMenu mListener;
private ImageView mHeader;
private TextView userName;
private TextView userEmail;
//region Constructors
public SimpleLeftMenuView(Context context) {
super(context);
mContext = context;
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
initLayout();
setData();
}
public SimpleLeftMenuView(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
initLayout();
setData();
}
public SimpleLeftMenuView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mContext = context;
mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
initLayout();
setData();
}
//endregion
private void initLayout(){
mInflater.inflate(R.layout.layout_left_menu, this);
mItemsList = (ListView) findViewById(R.id.menu_items_list);
mProgress = (ProgressBar) findViewById(R.id.progress);
mHeader = (ImageView) findViewById(R.id.header);
userName = (TextView) findViewById(R.id.userName);
userEmail = (TextView) findViewById(R.id.userEmail);
mHeader.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// do something
}
});
}
public void setSelectedSection(String idSection) {
mItemsAdapter.setLastSelectedSection(idSection);
}
public void setmListener(OnClickMenu mListener) {
this.mListener = mListener;
}
private void setData() {
List<String> sections = new ArrayList<>();
sections.add(mContext.getString(R.string.home_id));
sections.add(mContext.getString(R.string.login_id));
sections.add(mContext.getString(R.string.settings_id));
//.........
//sections.add(mContext.getString(R.string.exit_id));
mItemsAdapter = new MenuItemsAdapter(mContext, sections, new OnClickMenu() {
#Override
public void onClick(String id) {
mItemsAdapter.setLastSelectedSection(id);
if (mListener != null)
mListener.onClick(id);
}
});
mItemsList.setAdapter(mItemsAdapter);
mItemsList.setSelection(0);
mItemsList.setItemChecked(0, true);
}
}
You have to create the MenuItemAdapter.
public class MenuItemsAdapter extends BaseAdapter {
private Context mContext;
private static String lastSelectedSection;
private List<String> mSections;
private int currentTextcolor;
private OnClickMenu mListener;
public MenuItemsAdapter(Context context, List<String> sections, OnClickMenu listener) {
mContext = context;
mSections = sections;
mListener = listener;
lastSelectedSection = sections.get(0);
}
#Override
public int getCount() {
return mSections.size();
}
#Override
public String getItem(int position) {
return mSections.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
return getCustomView(position, convertView, parent);
}
public View getCustomView(final int position, View convertView, ViewGroup parent) {
final MenuItemHolder holder;
if (convertView==null){
LayoutInflater inflater = ((Activity) mContext).getLayoutInflater();
convertView = inflater.inflate(R.layout.layout_left_menu_item, parent, false);
holder = new MenuItemHolder(convertView);
convertView.setTag(holder);
}else {
holder = (MenuItemHolder) convertView.getTag();
}
Resources r = mContext.getResources();
int pxMarginSection = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 8, r.getDisplayMetrics());
holder.position = position;
holder.mLine.setVisibility(View.GONE);
holder.mTitle.setTextColor(mContext.getResources().getColor(R.color.primary));
holder.mIconView.setColorFilter(mContext.getResources().getColor(R.color.primary));
if (mSections.get(position).equals(mContext.getString(R.string.login_id))) {
holder.mIconView.setImageResource(R.drawable.ic_login_gp);
// holder.mIconView.setColorFilter(mContext.getResources().getColor(R.color.primary));
holder.mTitle.setText(mContext.getString(R.string.action_login));
holder.mLine.setVisibility(View.VISIBLE);
holder.mLayoutItem.setPadding(0, pxMarginSection, 0, pxMarginSection);
} else if (mSections.get(position).equals(mContext.getString(R.string.settings_id))) {
holder.mIconView.setImageResource(R.drawable.option);
holder.mTitle.setText(mContext.getString(R.string.action_settings));
holder.mLayoutItem.setPadding(0, pxMarginSection, 0, pxMarginSection);
holder.mLine.setVisibility(View.VISIBLE);
} else if (mSections.get(position).equals(mContext.getString(R.string.exit_id))) {
holder.mIconView.setImageResource(R.drawable.shutdown);
holder.mTitle.setText(mContext.getString(R.string.salir));
holder.mLayoutItem.setPadding(0, pxMarginSection, 0, pxMarginSection);
holder.mLine.setVisibility(View.VISIBLE);
}
holder.mLayoutItem.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
switch (motionEvent.getActionMasked()){
case MotionEvent.ACTION_DOWN:
currentTextcolor = holder.mTitle.getCurrentTextColor();
holder.mLayoutItemSelect.setBackgroundColor(mContext.getResources().getColor(R.color.primary));
holder.mTitle.setTextColor(mContext.getResources().getColor(R.color.text_info));
holder.mIconView.setColorFilter(mContext.getResources().getColor(R.color.text_info));
return true;
case MotionEvent.ACTION_UP:
holder.mLayoutItemSelect.setBackgroundResource(R.color.bgLeftMenu);
holder.mTitle.setTextColor(currentTextcolor);
holder.mIconView.setColorFilter(mContext.getResources().getColor(R.color.primary));
mListener.onClick(mSections.get(position));
return true;
case MotionEvent.ACTION_CANCEL:
holder.mLayoutItemSelect.setBackgroundColor(mContext.getResources().getColor(R.color.bgLeftMenu));
holder.mTitle.setTextColor(currentTextcolor);
holder.mIconView.setColorFilter(mContext.getResources().getColor(R.color.primary));
return true;
}
return false;
}
});
return convertView;
}
class MenuItemHolder {
// butterKnife
View view;
#Bind(R.id.title)
TextView mTitle;
#Bind(R.id.icon)
ImageView mIconView;
#Bind(R.id.layoutItem)
LinearLayout mLayoutItem;
#Bind (R.id.rl_line)
View mLine;
#Bind(R.id.layoutItemSelect)
LinearLayout mLayoutItemSelect;
int position;
public MenuItemHolder(View itemView) {
ButterKnife.bind(this, itemView);
view = itemView;
}
}
public void setLastSelectedSection(String idSection) {
lastSelectedSection = idSection;
}
}
Now you have to modify your current Activity:
Change your main activity layout to use DrawerLayout and add your custom view "SimpleLeftMenuView":
<android.support.v4.widget.DrawerLayout
android:id="#+id/drawerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android"
android:background="#EDEDED">
// YOUR CURRENT LAYOUT
<yourpackage.custom.SimpleLeftMenuView
android:id="#+id/navigation_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="#color/bgLeftMenu"/>
</android.support.v4.widget.DrawerLayout>
Activity class:
Add global variables:
protected #Bind(R.id.navigation_view) SimpleLeftMenuView mLeftMenuView;
protected #Bind(R.id.drawerLayout) DrawerLayout mDrawerLayout;
Set onclick listener. You can do an actions depends on the id:
mLeftMenuView.setmListener(new OnClickMenu() {
#Override
public void onClick(String id) {
Log.d("MENU", "ic_menu_hamburger clicked: " + id);
closeDrawer(null);
if (id.equals(getString(R.string.settings_id))) {
Intent intent = new Intent(MainActivity.this,
SettingsActivity.class);
MainActivity.this.startActivity(intent);
} else if (id.equals(getString(R.string.exit_id))) {
// salir
showRateDialogBeforeExit();
}
}
});
I have created my own interface OnClickMenu:
public interface OnClickMenu {
void onClick(String id);
}
And add action to open drawer from menu icon:
#Override
public void onBackPressed() {
if((mDrawerLayout) != null && (mDrawerLayout.isDrawerOpen(GravityCompat.START)))
closeDrawer(null);
else {
super.onBackPressed();
}
}
public void closeDrawer(DrawerLayout.DrawerListener listener) {
mDrawerLayout.setDrawerListener(listener);
mDrawerLayout.closeDrawers();
}
public void openDrawer() {
mDrawerLayout.setDrawerListener(null);
mDrawerLayout.openDrawer(GravityCompat.START);
}
Menu:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_home, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
openDrawer();
return true;
}
return super.onOptionsItemSelected(item);
}
add to app build.gradle
compile 'com.android.support:design:26.0.0'
compile 'com.jakewharton:butterknife:8.6.0'
Change all #Bind to #BindView
The easiest way for you would be using this library.
Its really easy to implement and its very flexible.
If you want to do it yourself, consider reading official docs about creating navigation drawer.
I've tried the MaterialDrawer library, as suggested by #yury-dombaev and I have to admit it's far easier to implement than the official Navigation Drawer.
It's possible to implement either with Android X dependencies or with the normal ones.
In my case, since I have the normal ones, I've to stick with the MaterialDrawer 6.0.9v. Although there's a migration guide that I'll give a look.
To implement the library within your current activity do the following:
Add the dependencies in your app build.gradle as explained in Setup 1 of the v 6.0.9 of the library: https://github.com/mikepenz/MaterialDrawer/tree/v6.0.9
Add your drawer in the onCreate() method of your Activity: new DrawerBuilder().withActivity(this).build();.
Now you've got a basic (and useless) lateral menu. So it's time you continue reading the Material Drawer documentation and add menu elements :)
I am using fragNav and bottombar plugin. I am trying to make a fullscreen fragment through a FrameLayout. By default, those plugins came with an actionBar which i delete in my theme with "Theme.AppCompat.Light.NoActionBar". But Once i did this there is still a white bar on top on my screen. When i look at hierarchyView it appears that my FrameLayout is not matching the parent but all my xml are setup with match_parent width and height..
MainActivity.java
public class MainActivity extends AppCompatActivity {
private BottomBar mBottomBar;
private FragNavController fragNavController;
private final int TAB_FIRST = FragNavController.TAB1;
private final int TAB_SECOND = FragNavController.TAB2;
private final int TAB_THIRD = FragNavController.TAB3;
private final int TAB_FOURTH = FragNavController.TAB4;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
List<Fragment> fragments = new ArrayList<>(4);
fragments.add(FirstFragment.newInstance(0));
fragments.add(SecondFragment.newInstance(0));
fragments.add(ThirdFragment.newInstance(0));
fragments.add(FourthFragment.newInstance(0));
fragNavController = new FragNavController(getSupportFragmentManager(), R.id.container, fragments);
//BottomBar menu
mBottomBar = BottomBar.attach(this, savedInstanceState);
mBottomBar.setItems(R.menu.bottombar_menu);
mBottomBar.setOnMenuTabClickListener(new OnMenuTabClickListener() {
#Override
public void onMenuTabSelected(#IdRes int menuItemId) {
//switch between tabs
switch (menuItemId) {
case R.id.bottomBarItemOne:
fragNavController.switchTab(TAB_FIRST);
break;
case R.id.bottomBarItemSecond:
fragNavController.switchTab(TAB_SECOND);
break;
case R.id.bottomBarItemThird:
fragNavController.switchTab(TAB_THIRD);
break;
case R.id.bottomBarItemFourth:
fragNavController.switchTab(TAB_FOURTH);
break;
}
}
#Override
public void onMenuTabReSelected(#IdRes int menuItemId) {
if (menuItemId == R.id.bottomBarItemOne) {
fragNavController.clearStack();
}
}
});
}
#Override
public void onBackPressed () {
if (fragNavController.getCurrentStack().size() > 1) {
fragNavController.pop();
} else {
super.onBackPressed();
}
}
#Override
protected void onSaveInstanceState (Bundle outState){
super.onSaveInstanceState(outState);
// Necessary to restore the BottomBar's state, otherwise we would
// lose the current tab on orientation change.
mBottomBar.onSaveInstanceState(outState);
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:id="#+id/container"
android:background="#color/black">
</FrameLayout>
FirstFragment.java
public class FirstFragment extends Fragment {
public class SwipeDeckAdapter extends BaseAdapter {
private List<String> data;
private Context context;
public SwipeDeckAdapter(List<String> data, Context context) {
this.data = data;
this.context = context;
}
#Override
public int getCount() {
return data.size();
}
#Override
public Object getItem(int position) {
return data.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
View v = convertView;
if(v == null){
LayoutInflater inflater = getActivity().getLayoutInflater();
// normally use a viewholder
v = inflater.inflate(R.layout.card_view, parent, false);
}
((TextView) v.findViewById(R.id.textView2)).setText(data.get(position));
v.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String item = (String)getItem(position);
Log.i("MainActivity", item);
}
});
return v;
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_home,container,false);
final SwipeDeck cardStack = (SwipeDeck) view.findViewById(R.id.swipe_deck);
cardStack.setHardwareAccelerationEnabled(true);
Button btn = (Button) view.findViewById(R.id.undobutton);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
cardStack.swipeTopCardLeft(180);
}
});
Button btn2 = (Button) view.findViewById(R.id.joinbutton);
btn2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
cardStack.swipeTopCardRight(180);
}
});
final ArrayList<String> testData = new ArrayList<>();
testData.add("0");
testData.add("1");
testData.add("2");
testData.add("3");
testData.add("4");
final SwipeDeckAdapter adapter = new SwipeDeckAdapter(testData, getActivity() );
cardStack.setAdapter(adapter);
cardStack.setEventCallback(new SwipeDeck.SwipeEventCallback() {
#Override
public void cardSwipedLeft(int position) {
Log.i("MainActivity", "card was swiped left, position in adapter: " + position);
}
#Override
public void cardSwipedRight(int position) {
Log.i("MainActivity", "card was swiped right, position in adapter: " + position);
}
#Override
public void cardsDepleted() {
Log.i("MainActivity", "no more cards");
}
#Override
public void cardActionDown() {
Log.i("MainActivity", "Down");
} ;
#Override
public void cardActionUp() {
Log.i("MainActivity", "Up");
};
});
return view;
}
public static FirstFragment newInstance(int index) {
FirstFragment f = new FirstFragment();
Bundle args = new Bundle();
args.putInt("index", index);
f.setArguments(args);
return f;
}
}
fragment_first.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:background="#color/black"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="io.MainActivity"
android:fitsSystemWindows="true">
<com.daprlabs.cardstack.SwipeLinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:swipedeck="http://schemas.android.com/apk/res-auto"
android:id="#+id/framelayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:weightSum="10">
<com.daprlabs.cardstack.SwipeDeck
android:id="#+id/swipe_deck"
android:layout_weight="8"
android:layout_width="match_parent"
android:layout_height="0dp"
swipedeck:card_spacing="0dp"
swipedeck:max_visible="3"
swipedeck:render_above="true"
swipedeck:rotation_degrees="15"
swipedeck:opacity_end="0.33">
</com.daprlabs.cardstack.SwipeDeck>
<RelativeLayout
android:id="#+id/rl"
android:layout_weight="2"
android:layout_width="match_parent"
android:layout_height="0dp">
<RelativeLayout
android:id="#+id/container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true">
<Button
android:id="#+id/undobutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Undo"
android:onClick="onClick"/>
<Button
android:id="#+id/joinbutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#id/undobutton"
android:text="Join"
android:onClick="onClick"/>
</RelativeLayout>
</RelativeLayout>
</com.daprlabs.cardstack.SwipeLinearLayout>
In your parent RelativeLayout in fragment_first can you remove the android:fitsSystemWindows="true", I think that may be the cause of the issue.