This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 3 years ago.
The application crashes with an error stating that the Recyclerview is being called on a null object. However I can't seem to pinpoint what is causing this issue. Any help would be very much appreciated. If anymore code is needed, do let me know and I'll edit it in.
Logcat error:
2019-10-30 23:59:15.235 10878-10878/com.example.zaphk.studenthelperapplication3 E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.zaphk.studenthelperapplication3, PID: 10878
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.zaphk.studenthelperapplication3/com.example.zaphk.studenthelperapplication3.view.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.widget.RecyclerView.setLayoutManager(android.support.v7.widget.RecyclerView$LayoutManager)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2861)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2943)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1630)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6626)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:811)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v7.widget.RecyclerView.setLayoutManager(android.support.v7.widget.RecyclerView$LayoutManager)' on a null object reference
at com.example.zaphk.studenthelperapplication3.view.MainActivity.onCreate(MainActivity.java:65)
at android.app.Activity.performCreate(Activity.java:7032)
at android.app.Activity.performCreate(Activity.java:7023)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1236)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2814)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2943)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1630)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6626)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:811)
MainActivity.java
package com.example.zaphk.studenthelperapplication3.view;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.design.widget.CoordinatorLayout;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
import com.example.zaphk.studenthelperapplication3.database.DatabaseHelper;
import com.example.zaphk.studenthelperapplication3.database.model.Note;
import com.example.zaphk.studenthelperapplication3.utils.MyDividerItemDecoration;
import com.example.zaphk.studenthelperapplication3.utils.RecyclerTouchListener;
import com.example.zaphk.studenthelperapplication3.R;
public class MainActivity extends AppCompatActivity {
private NotesAdapter mAdapter;
private List<Note> notesList = new ArrayList<>();
private CoordinatorLayout coordinatorLayout;
private RecyclerView recyclerView;
private TextView noNotesView;
private DatabaseHelper db;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_notes);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
coordinatorLayout = findViewById(R.id.coordinator_layout);
recyclerView = findViewById(R.id.recycler_view);
noNotesView = findViewById(R.id.empty_notes_view);
db = new DatabaseHelper(this);
notesList.addAll(db.getAllNotes());
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
showNoteDialog(false, null, -1);
}
});
mAdapter = new NotesAdapter(this, notesList);
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(mLayoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.addItemDecoration(new MyDividerItemDecoration(this, LinearLayoutManager.VERTICAL, 16));
recyclerView.setAdapter(mAdapter);
toggleEmptyNotes();
/**
* On long press on RecyclerView item, open alert dialog
* with options to choose
* Edit and Delete
* */
recyclerView.addOnItemTouchListener(new RecyclerTouchListener(this,
recyclerView, new RecyclerTouchListener.ClickListener() {
#Override
public void onClick(View view, final int position) {
}
#Override
public void onLongClick(View view, int position) {
showActionsDialog(position);
}
}));
}
/**
* Inserting new note in db
* and refreshing the list
*/
private void createNote(String note) {
// inserting note in db and getting
// newly inserted note id
long id = db.insertNote(note);
// get the newly inserted note from db
Note n = db.getNote(id);
if (n != null) {
// adding new note to array list at 0 position
notesList.add(0, n);
// refreshing the list
mAdapter.notifyDataSetChanged();
toggleEmptyNotes();
}
}
/**
* Updating note in db and updating
* item in the list by its position
*/
private void updateNote(String note, int position) {
Note n = notesList.get(position);
// updating note text
n.setNote(note);
// updating note in db
db.updateNote(n);
// refreshing the list
notesList.set(position, n);
mAdapter.notifyItemChanged(position);
toggleEmptyNotes();
}
/**
* Deleting note from SQLite and removing the
* item from the list by its position
*/
private void deleteNote(int position) {
// deleting the note from db
db.deleteNote(notesList.get(position));
// removing the note from the list
notesList.remove(position);
mAdapter.notifyItemRemoved(position);
toggleEmptyNotes();
}
/**
* Opens dialog with Edit - Delete options
* Edit - 0
* Delete - 0
*/
private void showActionsDialog(final int position) {
CharSequence colors[] = new CharSequence[]{"Edit", "Delete"};
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Choose option");
builder.setItems(colors, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
if (which == 0) {
showNoteDialog(true, notesList.get(position), position);
} else {
deleteNote(position);
}
}
});
builder.show();
}
/**
* Shows alert dialog with EditText options to enter / edit
* a note.
* when shouldUpdate=true, it automatically displays old note and changes the
* button text to UPDATE
*/
private void showNoteDialog(final boolean shouldUpdate, final Note note, final int position) {
LayoutInflater layoutInflaterAndroid = LayoutInflater.from(getApplicationContext());
View view = layoutInflaterAndroid.inflate(R.layout.note_dialog, null);
AlertDialog.Builder alertDialogBuilderUserInput = new AlertDialog.Builder(MainActivity.this);
alertDialogBuilderUserInput.setView(view);
final EditText inputNote = view.findViewById(R.id.note);
TextView dialogTitle = view.findViewById(R.id.dialog_title);
dialogTitle.setText(!shouldUpdate ? getString(R.string.lbl_new_note_title) : getString(R.string.lbl_edit_note_title));
if (shouldUpdate && note != null) {
inputNote.setText(note.getNote());
}
alertDialogBuilderUserInput
.setCancelable(false)
.setPositiveButton(shouldUpdate ? "update" : "save", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialogBox, int id) {
}
})
.setNegativeButton("cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialogBox, int id) {
dialogBox.cancel();
}
});
final AlertDialog alertDialog = alertDialogBuilderUserInput.create();
alertDialog.show();
alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Show toast message when no text is entered
if (TextUtils.isEmpty(inputNote.getText().toString())) {
Toast.makeText(MainActivity.this, "Enter note!", Toast.LENGTH_SHORT).show();
return;
} else {
alertDialog.dismiss();
}
// check if user updating note
if (shouldUpdate && note != null) {
// update note by it's id
updateNote(inputNote.getText().toString(), position);
} else {
// create new note
createNote(inputNote.getText().toString());
}
}
});
}
/**
* Toggling list and empty notes view
*/
private void toggleEmptyNotes() {
// you can check notesList.size() > 0
if (db.getNotesCount() > 0) {
noNotesView.setVisibility(View.GONE);
} else {
noNotesView.setVisibility(View.VISIBLE);
}
}
}
NotesAdapter.java
package com.example.zaphk.studenthelperapplication3.view;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.text.Html;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import com.example.zaphk.studenthelperapplication3.calendar.database.Calendar;
import com.example.zaphk.studenthelperapplication3.database.model.Note;
import com.example.zaphk.studenthelperapplication3.R;
public class NotesAdapter extends RecyclerView.Adapter<NotesAdapter.MyViewHolder> {
private Context context;
private List<Note> notesList;
public class MyViewHolder extends RecyclerView.ViewHolder {
public TextView note;
public TextView dot;
public TextView timestamp;
public MyViewHolder(View view) {
super(view);
note = view.findViewById(R.id.note);
dot = view.findViewById(R.id.dot);
timestamp = view.findViewById(R.id.timestamp);
}
}
public NotesAdapter(Context context, List<Note> notesList) {
this.context = context;
this.notesList = notesList;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.note_list_row, parent, false);
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
Note note = notesList.get(position);
holder.note.setText(note.getNote());
// Displaying dot from HTML character code
holder.dot.setText(Html.fromHtml("•"));
// Formatting and displaying timestamp
holder.timestamp.setText(formatDate(note.getTimestamp()));
}
#Override
public int getItemCount() {
return notesList.size();
}
/**
* Formatting timestamp to `MMM d` format
* Input: 2018-02-21 00:15:42
* Output: Feb 21
*/
private String formatDate(String dateStr) {
try {
SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date = fmt.parse(dateStr);
SimpleDateFormat fmtOut = new SimpleDateFormat("MMM d");
return fmtOut.format(date);
} catch (ParseException e) {
}
return "";
}
}
activity_notes.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/coordinator_layout"
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"
tools:context="com.example.zaphk.studenthelperapplication3.view.MainActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="#style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<include layout="#layout/content_main_timetable" />
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="#dimen/fab_margin"
app:srcCompat="#drawable/ic_add_white_24dp" />
</android.support.design.widget.CoordinatorLayout>
note_list_row.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/coordinator_layout"
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"
tools:context="com.example.zaphk.studenthelperapplication3.view.MainActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="#style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<include layout="#layout/content_main_timetable" />
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="#dimen/fab_margin"
app:srcCompat="#drawable/ic_add_white_24dp" />
</android.support.design.widget.CoordinatorLayout>
content_main_timetable.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context=".activities.TimetableActivity"
tools:showIn="#layout/app_bar_main">
<android.support.v4.view.ViewPager
android:id="#+id/viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v4.view.ViewPager>
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="#dimen/fab_margin"
android:src="#drawable/baseline_add_white_24"
tools:layout_editor_absoluteX="339dp"
tools:layout_editor_absoluteY="546dp" />
</FrameLayout>
There is no RecyclerView in your layout file, so when you call findViewById, no view is found, and your recyclerView is null, which is the reason for your null pointer exception.
In content_main_timetable did you mean RecyclerView instead of ViewPager? Replacing the view pager with a recycler view called recycler_view would fix your problem.
Your layout doesn't have a recyclerView. Which is why, findViewById returns a null. Your recyclerView is null, so you can't really set a layoutmanager on it. Fix your activity layout to include a recyclerview.
Related
This is the code I have been working on for a while. The only issue is I cannot seem to be able to get the sum of values input into the editText fields that are dynamically added into the program and then place them into a pie chart. The data is to be transferred from the second activity to the third where the third activity will add up all resource amounts and display them into a pie chart.
SecondActivity.class
package com.example.a4mob;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.text.InputType;
import android.view.MenuItem;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.ActionBarDrawerToggle;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.AppCompatSpinner;
import androidx.drawerlayout.widget.DrawerLayout;
import java.util.ArrayList;
import java.util.List;
public class SecondActivity extends AppCompatActivity implements View.OnClickListener {
public DrawerLayout drawerLayout;
public ActionBarDrawerToggle actionBarDrawerToggle;
private LinearLayout linearLayout;
private Button add;
//for button add resource
List<String> ColourList = new ArrayList<>();
ArrayList<Results> resultList = new ArrayList<>();
private Button submit;
private Number uinput;
#Override
protected void onCreate(Bundle savedInstance){
super.onCreate(savedInstance);
setContentView(R.layout.secondactivity);
// drawer layout instance to toggle the menu icon to open
// drawer and back button to close drawer
drawerLayout = findViewById(R.id.my_drawer_layout);
actionBarDrawerToggle = new ActionBarDrawerToggle(this, drawerLayout, R.string.nav_open, R.string.nav_close);
// pass the Open and Close toggle for the drawer layout listener
// to toggle the button
drawerLayout.addDrawerListener(actionBarDrawerToggle);
actionBarDrawerToggle.syncState();
// to make the Navigation drawer icon always appear on the action bar
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
ActionBar actionBar;
actionBar = getSupportActionBar();
// Define ColorDrawable object and parse color
// using parseColor method
// with color hash code as its parameter
ColorDrawable colorDrawable
= new ColorDrawable(Color.parseColor("grey"));
// Set BackgroundDrawable
actionBar.setBackgroundDrawable(colorDrawable);
//Adds more objects
linearLayout = findViewById(R.id.layout_list);
add = findViewById(R.id.CreateNew);
add.setOnClickListener(this);
ColourList.add("grey");
ColourList.add("green");
ColourList.add("blue");
ColourList.add("yellow");
// Creating submit button click listener
submit = findViewById(R.id.Submit);
submit.setOnClickListener(this);
}
public void onClick(View view){
switch (view.getId()){
case R.id.CreateNew:
addView();
break;
case R.id.Submit:
if(isValid()){
Intent intent = new Intent(SecondActivity.this, ThirdActivity.class);
Bundle bundle = new Bundle();
bundle.putSerializable("list", resultList);
intent.putExtras(bundle);
startActivity(intent);
}
break;
}
}
private boolean isValid() {
resultList.clear();
boolean valid = true;
for(int i = 0; i < linearLayout.getChildCount(); i++){
View resultView = linearLayout.getChildAt(i);
EditText resultName = (EditText) resultView.findViewById(R.id.RName);
EditText resultNumber = (EditText) resultView.findViewById(R.id.RAmount);
AppCompatSpinner COP = (AppCompatSpinner) resultView.findViewById(R.id.ColourOP);
Results results = new Results();
if(!resultName.getText().toString().equals("")){
results.setResName(resultName.getText().toString());
}else{
valid = false;
break;
}
if(!resultNumber.getText().toString().equals("")){
results.setResAmount(Integer.parseInt(resultNumber.getText().toString()));
}else{
valid = false;
break;
}
if(COP.getSelectedItemPosition()!=0){
}else{
valid = false;
break;
}
resultList.add(results);
}
if(resultList.size() == 0){
valid = false;
Toast.makeText(this, "Complete all fields first", Toast.LENGTH_SHORT).show();
} else if(!valid){
Toast.makeText(this, "Enter details correctly", Toast.LENGTH_SHORT).show();
}
return valid;
}
public void addAmount(){
for(int i = 0; i < linearLayout.getChildCount(); i++) {
View resultView = linearLayout.getChildAt(i);
EditText resultNumber = (EditText) resultView.findViewById(R.id.RAmount);
Results results = new Results();
}
}
private void sub(){
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Please input inventory space:");
// Set up the input
final EditText input = new EditText(this);
// Specify the type of input expected; this, for example, sets the input as a password, and will mask the text
input.setInputType(InputType.TYPE_CLASS_NUMBER);
builder.setView(input);
// Set up the buttons
builder.setPositiveButton("Continue", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
uinput = input.getInputType();
changeAct();
}
});
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
builder.show();
}
private void changeAct(){
Intent intent = new Intent(this, ThirdActivity.class);
startActivity(intent);
}
private void addView(){
View newResource = getLayoutInflater().inflate(R.layout.row_add_data, null, false);
ImageView imageClose = (ImageView)newResource.findViewById(R.id.Remove);
TextView RN = (TextView) newResource.findViewById(R.id.RName);
TextView RA = (TextView) newResource.findViewById(R.id.RAmount);
AppCompatSpinner COP = (AppCompatSpinner) newResource.findViewById(R.id.ColourOP);
ArrayAdapter arrayAdapter = new ArrayAdapter(this, android.R.layout.simple_spinner_item, ColourList);
COP.setAdapter(arrayAdapter);
imageClose.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
removeView(newResource);
}
});
linearLayout.addView(newResource);
}
private void removeView(View view){
linearLayout.removeView(view);
}
#Override
public boolean onOptionsItemSelected(#NonNull MenuItem item) {
if (actionBarDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onPointerCaptureChanged(boolean hasCapture) {
super.onPointerCaptureChanged(hasCapture);
}
}
ThirdActivity.class
package com.example.a4mob;
import androidx.annotation.NonNull;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.ActionBarDrawerToggle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import java.util.ArrayList;
public class ThirdActivity extends AppCompatActivity {
RecyclerView recycle_results;
ArrayList<Results> resultList = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.thirdactivity);
recycle_results = findViewById(R.id.res_results);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this, RecyclerView.VERTICAL, false);
recycle_results.setLayoutManager(linearLayoutManager);
resultList = (ArrayList<Results>) getIntent().getExtras().getSerializable("list");
recycle_results.setAdapter(new ResultsAdapter(resultList));
}
}
Results.class
package com.example.a4mob;
import java.io.Serializable;
public class Results implements Serializable {
public String resourceName;
public int resourceAmount;
public int totalAmount;
public Results(){
}
public int getTotalAmount() {
return totalAmount;
}
public void setTotalAmount(int totalAmount) {
this.totalAmount = totalAmount;
}
public int getResAmount() {
return resourceAmount;
}
public void setResAmount(int resourceAmount) {
this.resourceAmount = resourceAmount;
}
public Results(String resourceName, int resourceAmount){
this.resourceName = resourceName;
this.resourceAmount = resourceAmount;
}
public String getResName() {
return resourceName;
}
public void setResName(String resourceName) {
this.resourceName = resourceName;
}
}
ResultsAdapter.class
package com.example.a4mob;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
public class ResultsAdapter extends RecyclerView.Adapter<ResultsAdapter.ResultsView> {
ArrayList<Results> resultList = new ArrayList<>();
int total;
public ResultsAdapter(ArrayList<Results> resultList) {
this.resultList = resultList;
}
#NonNull
#Override
public ResultsView onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_results,parent,false);
return new ResultsView(view);
}
#Override
public void onBindViewHolder(#NonNull ResultsView holder, int position) {
Results results = resultList.get(position);
holder.resourceName.setText(results.getResName());
holder.resourceAmount.setText(String.valueOf(results.getResAmount()));
}
#Override
public int getItemCount() {
return resultList.size();
}
public class ResultsView extends RecyclerView.ViewHolder{
TextView resourceName, resourceAmount, resourceTotal;
public ResultsView(#NonNull View itemView) {
super(itemView);
resourceName = (TextView) itemView.findViewById(R.id.resNa);
resourceAmount = (TextView) itemView.findViewById(R.id.resAm);
resourceTotal = (TextView) itemView.findViewById(R.id.resTot);
}
}
}
thirdactivity.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
tools:context=".ThirdActivity">
<LinearLayout
android:id="#+id/layoutThird"
android:layout_width="0dp"
android:layout_height="0dp"
android:orientation="horizontal"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/res_results"
android:layout_width="match_parent"
android:layout_height="match_parent"></androidx.recyclerview.widget.RecyclerView>
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
row_results.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
app:cardBackgroundColor="#color/white"
android:layout_margin="5dp"
android:layout_marginBottom="20dp"
app:cardCornerRadius="10dp"
app:cardElevation="10dp">
<LinearLayout
android:padding="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:weightSum="1"
android:layout_marginBottom="0dp">
<TextView
android:id="#+id/resNa"
android:layout_marginLeft="5dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Resource Name"
android:textSize="18sp"
android:textColor="#color/black"></TextView>
<TextView
android:id="#+id/resAm"
android:layout_marginLeft="5dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Resource Amount"
android:textSize="14sp"
android:textColor="#color/black"></TextView>
<TextView
android:id="#+id/resTot"
android:layout_marginLeft="5dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Resource Amount"
android:textSize="14sp"
android:textColor="#color/black"></TextView>
</LinearLayout>
</androidx.cardview.widget.CardView>
I have tried everything including adding
implementation 'com.android.support:recyclerview-v7:27.0.0'
These are my related java classes
Home.java
package com.example.re_search;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.example.re_search.model.PostModel;
import java.util.ArrayList;
import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class Home extends Fragment{
private ArrayList<Integer> pkPost = new ArrayList<>();
private ArrayList<String> namePost = new ArrayList<>();
private RecyclerView recyclerView;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.post_list, container, false);
recyclerView = rootView.findViewById(R.id.recycler_category_list);
if ( InternetUtil.isInternetOnline(getActivity()) ){
ClearList();
showAllPosts();
}
getActivity().setTitle("Clusters");
return rootView;
}
private void showAllPosts() {
Log.i("All posts showed", "All posts showed");
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(PostApi.API_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
Log.i("Retrofit build", "Retrofit build");
PostApi postApi= retrofit.create(PostApi.class);
Log.i("Postapi createdd", "Postapi createdd");
Call<List<PostModel>> call = postApi.getListPost();
Log.i("Call list called", "Call list called");
call.enqueue(new Callback<List<PostModel>>() {
#Override
public void onResponse(Call<List<PostModel>> call, Response<List<PostModel>> response) {
Log.i("Response Received", "Response Received");
if(response.isSuccessful()){
Log.i("Response Received", "Response Received");
if (response.body() != null) {
List<PostModel> postList = response.body();
for(PostModel h:postList){
//Integer cat_id = h.getId();
//pkPost.add(cat_id);
String cat_name = h.getTitle();
namePost.add(cat_name);
}
initRecyclerView();
}
}else {
Log.d("fail", "fail");
}
}
#Override
public void onFailure(Call<List<PostModel>> call, Throwable t) {
Log.d("fail", t.getMessage() == null ? "" : t.getMessage());
}
});
}
private void initRecyclerView(){
Log.d("Home", "initRecyclerView: init recyclerview.");
RecyclerHomeList adapter = new RecyclerHomeList(getActivity(), pkPost, namePost);
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
}
public void ClearList()
{
pkPost.clear();
namePost.clear();
RecyclerHomeList adapter = new RecyclerHomeList(getActivity(), pkPost, namePost);
adapter.notifyDataSetChanged();
recyclerView.setAdapter(adapter);
}
#Override
public void onResume() {
super.onResume();
getView().setFocusableInTouchMode(true);
getView().requestFocus();
getView().setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK){
getActivity().finish();
return true;
}
return false;
}
});
}
}
RecyclerHomeList.java
package com.example.re_search;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import android.widget.TextView;
import java.util.ArrayList;
public class RecyclerHomeList extends RecyclerView.Adapter<RecyclerHomeList.ViewHolder>{
private static final String TAG = "RecyclerProfileListAdapter";
private ArrayList<Integer> pkPost = new ArrayList<>();
private ArrayList<String> namePost = new ArrayList<>();
private Context mContext;
public RecyclerHomeList(Context context, ArrayList<Integer> rId, ArrayList<String> rName) {
pkPost = rId;
namePost = rName;
mContext = context;
}
#Override
public RecyclerHomeList.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.post_list_item, parent, false);
RecyclerHomeList.ViewHolder holder = new RecyclerHomeList.ViewHolder(view);
return holder;
}
#Override
public void onBindViewHolder(RecyclerHomeList.ViewHolder holder, final int position) {
holder.TId.setText(String.valueOf(pkPost.get(position)));
holder.TName.setText(namePost.get(position));
holder.parentLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
// Bundle bundle = new Bundle();
// bundle.putInt("post_id",pkPost.get(position)); // Put anything what you want
// AppCompatActivity activity = (AppCompatActivity) view.getContext();
// Fragment myFragment = new ShowPost();
// myFragment.setArguments(bundle);
// activity.getSupportFragmentManager()
// .beginTransaction()
// .replace(R.id.fragment_container, myFragment)
// .addToBackStack(null)
// .commit();
}
});
}
#Override
public int getItemCount() {
return pkPost.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
TextView TId;
TextView TName;
RelativeLayout parentLayout;
public ViewHolder(View itemView) {
super(itemView);
TId = itemView.findViewById(R.id.post_listitem_id);
TName = itemView.findViewById(R.id.post_listitem_name);
parentLayout = itemView.findViewById(R.id.parent_layout);
}
}
}
Related XML Files:
post_list.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<RelativeLayout
android:id="#+id/footer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_gravity="center"
android:gravity="center">
<fragment
android:id="#+id/button_fragment1"
android:name="com.example.re_search.Footer"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</RelativeLayout>
<LinearLayout
android:id="#+id/scroll_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_above="#+id/footer"
android:fillViewport="true">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#F3F3F3"
android:orientation="vertical">
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/recycler_category_list">
</android.support.v7.widget.RecyclerView>
</LinearLayout>
</LinearLayout>
</RelativeLayout>
</android.support.constraint.ConstraintLayout>
post_list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/parent_layout">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp"
android:layout_marginTop="8dp"
android:layout_marginRight="16dp"
android:orientation="vertical"
android:background="#ffffff">
<LinearLayout
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_marginRight="16dp"
android:layout_marginLeft="16dp"
android:layout_marginTop="9dp"
android:layout_marginBottom="10dp"
>
<TextView
android:id="#+id/post_listitem_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
/>
<TextView
android:id="#+id/post_listitem_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
/>
</LinearLayout>
</LinearLayout>
</RelativeLayout>
This is the error trace
I/TetheringManager: registerTetheringEventCallback:com.example.re_search
W/ample.re_searc: Accessing hidden method Ldalvik/system/CloseGuard;->get()Ldalvik/system/CloseGuard; (greylist,core-platform-api, reflection, allowed)
Accessing hidden method Ldalvik/system/CloseGuard;->open(Ljava/lang/String;)V (greylist,core-platform-api, reflection, allowed)
Accessing hidden method Ldalvik/system/CloseGuard;->warnIfOpen()V (greylist,core-platform-api, reflection, allowed)
I/Response Received: Response Received
I/Token: 84639f11977c3078fa92d4f7abc0cb316ef91847
D/CompatibilityChangeReporter: Compat change id reported: 147798919; UID 10121; state: DISABLED
I/All posts showed: All posts showed
I/Retrofit build: Retrofit build
I/Postapi createdd: Postapi createdd
I/Call list called: Call list called
E/RecyclerView: No layout manager attached; skipping layout
I/Response Received: Response Received
Response Received
D/Home: initRecyclerView: init recyclerview.
I am trying to send a get response to the django server but this error is killing my app after the login. please help please.
This is my grade file
plugins {
id 'com.android.application'
}
android {
compileSdkVersion 27
defaultConfig {
applicationId "com.example.re_search"
minSdkVersion 14
targetSdkVersion 27
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
//noinspection GradleCompatible
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support.constraint:constraint-layout:1.1.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation 'com.squareup.retrofit2:retrofit:2.3.0'
implementation 'com.squareup.retrofit2:converter-gson:2.3.0'
implementation 'com.android.support:recyclerview-v7:27.0.0'
//implementation 'com.android.support.constraint:constraint-layout:1.0.2'
}
You need to set your adapter after you have set your LayoutManager.
Change from this:
recyclerView.setAdapter(adapter);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
to this:
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
recyclerView.setAdapter(adapter);
The call to initRecyclerView() is done on a background thread, that's the issue.
Make the call inside of Oncreate and update values using adapter.datasetchanged()-methods.
You're getting this error because you're initializing your RecyclerView from an asynchronous callback.
You should initialize your RecyclerView inside onCreateView():
// Set up your RecyclerView with the appropriate Layout Manager
RecyclerView myRecycler = findViewById(R.id.my_recycler_id);
myRecycler.setLayoutManager(new LinearLayoutManager(this));
// Create your data set
myData = new ArrayList<MyDataType>();
// Create an instance of your adapter passing the data set into the constructor
myAdapter = new MyAdapter(this, myData);
// Set the Adapter on the RecyclerView directly within onCreate
// so that it doesn't get skipped
myRecycler.setAdapter(myAdapter);
Inside of your Adapter class, create a function to update your data set:
public void updateData(ArrayList<MyDataType> newDataSet){
myAdapterDataSet = newDataSet;
// Let the Adapter know the data has changed and the view should be refreshed
notifyDataSetChanged();
}
Inside of your asynchronous callback, update your adapter:
#Override
public void onDataChange(DataSnapshot snapshot){
// Add the new data to your data set ex. myData.add(newData)
// ...
// After adding to the data set,
// update the data using a custom function you define in your Adapter's class
myAdapter.updateData(myData);
}
My app's MainActivity has a ViewPager which has three children(swipe views). When swiped to last child, the ActionBar gets two menu items. On clicking one item, a Dialog pops up to add a name of an item into a Database. On clicking second menu item, another Dialog pops up that prompts user to enter the name of the item that is to be removed from the Database. These Dialogs are getting constructed by separate Dialog Fragments. Basically what I want is to get the callback event from the Dialog that the positive or negative button has been clicked and wanna perform some action in the fragment which is as I mentioned is the last child of my ViewPager. I've seen the Android documentation as well as a Youtube video to learn how to implement the interface, yet my app's crashing.
Here's the code for my DialogFragment which shows a Dialog that prompts the user to enter input and save it to the Database.
package com.example.android.mybusiness;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.DialogFragment;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
public class AddCigaretteNameDialog extends DialogFragment {
EditText userInput;
String cigaretteName;
DbHelper dbHelper;
public AddCigaretteNameDialogListener listener;
public interface AddCigaretteNameDialogListener {
void onDialogPositiveClick(String name);
}
#NonNull
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
dbHelper = new DbHelper(getContext());
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
// SET THE TITLE FOR THE DIALOG.
builder.setTitle(R.string.add_title);
// GET THE LAYOUT INFLATOR
LayoutInflater inflater = getActivity().getLayoutInflater();
// INFLATE THE LAYOUT AND PUT IT INTO A VARIABLE.
// PASS NULL AS PARENT VIEW, BECAUSE IT'S GOING IN THE DIALOG
View view = inflater.inflate(R.layout.edit_text_for_dialogs, null);
// GET THE EDIT_TEXT FROM THE 'VIEW' VARIABLE.
userInput = view.findViewById(R.id.cigarette_name_user_input);
// SET THE LAYOUT FOR THE DIALOG
builder.setView(view);
// SET ACTION BUTTONS
builder.setPositiveButton(R.string.save, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
// GET THE USER INPUT FROM THE EDIT_TEXT ABOVE AND PUT IT INTO A VARIABLE.
cigaretteName = userInput.getText().toString();
// PUT THE USER INPUT IN THE DATABASE.
Boolean result = dbHelper.insertCigaretteName(cigaretteName);
if (result) {
// SHOW SUCCESS MESSAGE THAT CIGARETTE NAME HAS BEEN INSERTED.
Toast.makeText(getContext(), cigaretteName + " has been added successfully!", Toast.LENGTH_SHORT).show();
listener.onDialogPositiveClick(cigaretteName);
} else {Toast.makeText(getContext(), "Something is wrong", Toast.LENGTH_SHORT).show();}
}
})
.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
dismiss();
}
});
// RETURN THE DIALOG.
return builder.create();
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
// VERIFY THAT THE HOST ACTIVITY IMPLEMENTS THE CALLBACK INTERFACE
try {
listener = (AddCigaretteNameDialogListener) getTargetFragment();
} catch (ClassCastException e){
// THE ACTIVITY DOESN'T IMPLEMENT INTERFACE, THROW AN EXCEPTION.
throw new ClassCastException(getActivity().toString() + " must implement listener");
}
}
}
And here's the fragment which is the last child of the view pager.
package com.example.android.mybusiness;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.Toast;
/**
* A simple {#link Fragment} subclass.
*/
public class Purchase extends Fragment implements AddCigaretteNameDialog.AddCigaretteNameDialogListener {
Spinner spinner;
DbHelper dbHelper;
ArrayAdapter<String> arrayAdapter;
// FRAGMENT'S CONSTRUCTOR.
public Purchase() { }
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// KIND OF REQUIREMENT FOR OPTION MENUS.
setHasOptionsMenu(true);
// INSTANTIATING THE OBJECT TO RUN A FUNCTION, WHICH GETS THE CIGARETTES NAME.
dbHelper = new DbHelper(getContext());
// Inflate the layout for this fragment
// AND PUT IT INTO A VARIABLE SO WIDGETS CAN BE ACCESSED.
View view = inflater.inflate(R.layout.fragment_purchase, container, false);
// FIND THE spinner.
spinner = view.findViewById(R.id.spinner);
// CREATING THIS ADAPTER TO POPULATE THE SPINNER WIDGET.
arrayAdapter = new ArrayAdapter<String>(getContext(), android.R.layout.simple_list_item_1, dbHelper.getAllCigaretteNames());
// SETTING THE ADAPTER TO THE SPINNER, WHICH WILL PROVIDE THE CONTENT TO BE SELECTED BY ME.
spinner.setAdapter(arrayAdapter);
return view;
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu, menu);
super.onCreateOptionsMenu(menu, inflater);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.add_cigarette:
AddCigaretteNameDialog addCigaretteNameDialog = new AddCigaretteNameDialog();
addCigaretteNameDialog.show(getFragmentManager(), "add_cigarette_name");
return true;
case R.id.remove_cigarette:
RemoveCigaretteNameDailog RemoveCigaretteNameDailog = new RemoveCigaretteNameDailog();
RemoveCigaretteNameDailog.show(getFragmentManager(), "add_cigarette_name");
; return true;
default:
return super.onOptionsItemSelected(item);
}
}
#Override
public void onDialogPositiveClick(String name) {
arrayAdapter.add(name);
}
}
Here's the crash log:
12-07 13:13:59.278 25327-25327/com.example.android.mybusiness
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.android.mybusiness, PID: 25327
java.lang.NullPointerException: Attempt to invoke interface method 'void
com.example.android.mybusiness.AddCigaretteNameDialog$AddCigaretteNameDialogListener.onDialogPositiveClick(java.lang.String)'
on a null object reference
at com.example.android.mybusiness.AddCigaretteNameDialog$2.onClick(AddCigaretteNameDialog.java:58)
at com.android.internal.app.AlertController$ButtonHandler.handleMessage(AlertController.java:162)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5296)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:912)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:707)
Line 58 is
listener.onDialogPositiveClick(cigaretteName);
Thanks in advance!
If you use custom dialog class with custom view this would solve your problem. I am posting a code below which shows a custom dialog with views. first of all create a layout file for your dialog design by name dlg_add_cigarette_name inside layout folder
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:background="#drawable/dialog_background_inset"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layout_marginLeft="16dp"
android:text="Cigrate Name:"
android:id="#+id/tv_label_total"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/layout_total_update"
android:orientation="horizontal"
android:layout_below="#+id/tv_label_total"
android:weightSum="2"
>
<EditText
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.5"
android:layout_marginLeft="16dp"
android:layout_marginRight="10dp"
android:id="#+id/et_cgrate_name"
android:inputType="text"
/>
</LinearLayout>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/layout_total_update"
android:layout_alignParentRight="true"
android:background="#android:color/transparent"
android:layout_marginRight="70dp"
android:text="OK"
android:layout_marginBottom="20dp"
android:layout_marginTop="20dp"
android:id="#+id/button_ok"
android:textColor="#color/colorPrimaryDark"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/layout_total_update"
android:layout_toLeftOf="#+id/button_ok"
android:layout_marginRight="30dp"
android:text="Cancel"
android:layout_marginBottom="20dp"
android:layout_marginTop="20dp"
android:background="#android:color/transparent"
android:id="#+id/button_cancel"
android:textColor="#color/colorPrimaryDark"
/>
Now inside drawable folder create a new file by name dialog_background_insetand update the file by following code
<?xml version="1.0" encoding="utf-8"?>
<inset
xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="#color/white"
android:insetRight="15dp"
android:insetLeft="15dp">
</inset>
and now in your AddCigaretteNameDialog file update the class by following code
import android.annotation.SuppressLint;
import android.app.Dialog;
import android.content.Context;
import android.content.res.Resources;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.FragmentManager;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.drinkwater.reminder.watertracker.R;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import butterknife.Unbinder;
public class AddCigaretteNameDialog extends DialogFragment {
private static final float DIM_AMOUNT = 0.4f;
#BindView(R.id.tv_label_total)
TextView tvLabelTotal;
#BindView(R.id.et_cgrate_name)
EditText etCgrateName;
#BindView(R.id.layout_total_update)
LinearLayout layoutTotalUpdate;
#BindView(R.id.button_ok)
Button buttonOk;
#BindView(R.id.button_cancel)
Button buttonCancel;
#OnClick(R.id.button_cancel)
public void onClick(){
dismiss();
}
#OnClick(R.id.button_ok)
public void onClickOkay(){
unitCallBack.addCigarette(cigaretteName);
}
private Unbinder mUnbinder;
private AddCigaretteName unitCallBack;
private String cigaretteName;
public AddCigaretteNameDialog() {
}
public static AddCigaretteNameDialog newInstance(String title) {
AddCigaretteNameDialog frag = new AddCigaretteNameDialog();
Bundle args = new Bundle();
args.putString("title", title);
frag.setArguments(args);
return frag;
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (unitCallBack == null && context instanceof AddCigaretteName) {
unitCallBack = (AddCigaretteName) context;
}
}
#Override
public void onDetach() {
super.onDetach();
unitCallBack = null;
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final Dialog dialog = super.onCreateDialog(savedInstanceState);
final Window window = dialog.getWindow();
if (window != null) {
window.requestFeature(Window.FEATURE_NO_TITLE);
window.setBackgroundDrawableResource(android.R.color.transparent);
WindowManager.LayoutParams windowLayoutParams = window.getAttributes();
windowLayoutParams.dimAmount = DIM_AMOUNT;
}
dialog.setCancelable(false);
dialog.setCanceledOnTouchOutside(false);
return dialog;
}
#SuppressLint("NewApi")
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.test, container, false);
mUnbinder = ButterKnife.bind(this, view);
etCgrateName.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
cigaretteName=s.toString();
}
#Override
public void afterTextChanged(Editable s) {
}
});
return view;
}
#Override
public void onResume() {
super.onResume();
final int width = getScreenWidth();
int height = getScreenHeight() / 2;
changeWindowSizes(width, ViewGroup.LayoutParams.WRAP_CONTENT);
}
private void changeWindowSizes(int width, int height) {
final Window window = getDialog().getWindow();
if (window != null) {
window.setLayout(width, height);
}
}
#Override
public void onDestroyView() {
super.onDestroyView();
mUnbinder.unbind();
}
#Override
public int getTheme() {
return R.style.CustomDialog;
}
public interface AddCigaretteName {
void addCigarette(String name);
}
public static int getScreenWidth() {
return Resources.getSystem().getDisplayMetrics().widthPixels;
}
public static int getScreenHeight() {
return Resources.getSystem().getDisplayMetrics().heightPixels;
}
}
create a custom theme inside styles file
<style name="CustomDialog" parent="Theme.AppCompat.Light.Dialog">
<item name="android:windowAnimationStyle">#style/CustomDialogAnimation</item>
</style>
<style name="CustomDialogAnimation">
<item name="android:windowEnterAnimation">#anim/translate_left_side</item>
<item name="android:windowExitAnimation">#anim/translate_right_side</item>
</style>
create a package anim inside resfolder and create two files translate_left_sideand translate_right_side
translate_right_side
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromXDelta="0%" android:toXDelta="100%"
android:fromYDelta="0%" android:toYDelta="0%"
android:duration="600"/>
translate_left_side
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="600"
android:fromXDelta="100%"
android:toXDelta="0%"/>
Your AddCigrateDialog is ready to appear.Now its time to call this dialog from button click.Inside Purchase make an object of AddCigaretteDialog class globally
AddCigaretteNameDialog addCigaretteNameDialog;
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.add_cigarette:
addCigaretteNameDialog= new AddCigaretteNameDialog();
addCigaretteNameDialog= AddCigaretteNameDialog.newInstance("AddCigrateNameDialog");
addCigaretteNameDialog.show(manager,"show");
return true;
case R.id.remove_cigarette:
RemoveCigaretteNameDailog RemoveCigaretteNameDailog = new RemoveCigaretteNameDailog();
RemoveCigaretteNameDailog.show(getFragmentManager(), "add_cigarette_name");
; return true;
default:
return super.onOptionsItemSelected(item);
}
}
And yes don't forget to implement the interface of AddCigaretteDialog inside Purchase dialog
As I am using ButterKnife dependency add the following lines inside your app's gradle file
inal BUTTER_KNIFE_VERSION = "8.8.1"
implementation "com.jakewharton:butterknife:$BUTTER_KNIFE_VERSION"
annotationProcessor "com.jakewharton:butterknife-compiler:$BUTTER_KNIFE_VERSION"
Hi I been trying for a while to figure this out and checked a lot of post. I am having this problem when I switch to a new tab only the XML layout is showing. Though when I start on the first tab and fragment the json content shows up how I like. I am not sure how to get the json content to change for a new tab.
Fragment
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.koushikdutta.async.future.FutureCallback;
import com.koushikdutta.ion.Ion;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.Random;
/**
* A simple {#link Fragment} subclass.
*/
public class TVFragment extends Fragment {
public TVFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.tv_activity, container, false);
ArrayList<String> media = new ArrayList<String>();
media.add("movie1");
media.add("movie2");
media.add("movie3");
this.loadMovieInfo(media);
// loadMoviePoster(media);
return rootView;
}
private void loadMovieInfo(ArrayList<String> media) {
Random random = new Random();
int x = (int) random.nextInt(media.size()) * 1;
//Use Ion to get json info for movie from movie/tv api.
Ion.with(this)
.load("http://www.omdbapi.com/?t=" + media.get(x)
+ "&apikey0000")
.asString()
.setCallback(new FutureCallback<String>() {
#Override
public void onCompleted(Exception e, String result) {
try {
// create json object
JSONObject json = new JSONObject(result);
//get json title and poster from the json object.
String name = json.getString("Title");
String urlString = json.getString("Poster");
//get TextView to display title
TextView mediaName = (TextView) getActivity().findViewById(R.id.synopsis_text_view);
mediaName.setText(name);
/* create new DownloadImageTask class for displaying image from url. Picasso API can be used instead if wanted to view picture as well.
this needs to be used since the app will crash due to nature of threading, so AsyncTask is implemented.
*/
new DownloadImageTask((ImageView) getActivity().findViewById(R.id.poster)).execute(urlString);
} catch (JSONException jsone) {
Log.wtf("Json Import problems", jsone);
}
}
});
}
}
MainActivity
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.design.widget.TabLayout;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
/**
* Created by Samuel on 2/12/2018.
*/
public class TechnologyResultsActivity extends AppCompatActivity {
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Set the content of the activity to use the tv_activitylayout file
setContentView(R.layout.tab_viewpager_activity);
ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
MediaTypeAdapter adapter = new MediaTypeAdapter(getSupportFragmentManager(),getApplicationContext());
viewPager.setAdapter(adapter);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);
}
}
Adapter
import android.content.Context;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
/**
* Created by Samuel on 2/14/2018.
*/
public class MediaTypeAdapter extends FragmentPagerAdapter {
public MediaTypeAdapter(FragmentManager fragmentManager, Context applicationContext){
super(fragmentManager);
}
#Override
public Fragment getItem(int position) {
if (position == 0) {
return new TVFragment();
} else if (position == 1) {
return new MovieFragment();
}
else {
return new MovieFragment();
}
}
#Override
public int getCount() {
return 2;
}
#Override
public CharSequence getPageTitle(int position) {
if(position == 0){
return "TV";
} else {
return "MOVIES";
}
}
}
tablayout
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="#color/colorPrimary"
android:orientation="vertical">
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMode="fixed">
</android.support.design.widget.TabLayout>
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v4.view.ViewPager>
</LinearLayout>
movie_activity layout
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
xmlns:tools="http://schemas.android.com/tools">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="bottom"
android:paddingBottom="16dp">
<ImageView
android:id="#+id/poster"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_gravity="center"
android:paddingTop="16dp"
android:paddingBottom="16dp"
tools:src="#drawable/poster"
android:layout_weight="1"
/>
<ScrollView
android:id="#+id/synopsis_scroll"
android:layout_width="match_parent"
android:layout_height="81dp"
android:padding="8dp">
<TextView
android:id="#+id/synopsis_text_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:text="Academy Award nominee, heart-warming, hit comedy from producer Judd Apatow (Bridesmaids and Trainwreck). The Big Sick is based on the real-life courtship between Pakistan-born comedian Kumail Nanjiani (Nanjiani) and grad student Emily Gordon (Zoe Kazan) who fall in love but struggle while dealing with Emily's mysterious illness and their families culture clash. Also staring Ray Romano and Holly Hunter. Included with Prime."/>
</ScrollView>
</LinearLayout>
</LinearLayout>
you have to create a new class moviefragment and have to write code to fetch movies in that.
public class MovieFragment extends Fragment{
TechnologyResultsActivity technology;
Context context;
#Override
public void onAttach(Context context) {
super.onAttach(context);
this.context=context;
technology= (TechnologyResultsActivity) context;
}
public static Fragment newInstance(Bundle bundle){
MovieFragment movie=new MovieFragment();
if(bundle!=null){
movie.setArguments(bundle);
}
return movie;
}
#Override
public void onResume() {
super.onResume();
// this will only called when fragment is visible to user
if(isVisible()) {
if (Constant.isInternetConnected(homeActivity)) {
ArrayList<String> media = new ArrayList<String>();
media.add("movie1");
media.add("movie2");
media.add("movie3");
loadMovieInfo(media)
} else {
Toast.makeText(homeActivity, "No Internet Connection", Toast.LENGTH_SHORT).show();
}
}
}
private void loadMovieInfo(ArrayList<String> media) {
Random random = new Random();
int x = (int) random.nextInt(media.size()) * 1;
//Use Ion to get json info for movie from movie/tv api.
Ion.with(this)
.load("http://www.omdbapi.com/?t=" + media.get(x)
+ "&apikey0000")
.asString()
.setCallback(new FutureCallback<String>() {
#Override
public void onCompleted(Exception e, String result) {
try {
// create json object
JSONObject json = new JSONObject(result);
//get json title and poster from the json object.
String name = json.getString("Title");
String urlString = json.getString("Poster");
//get TextView to display title
TextView mediaName = (TextView) getActivity().findViewById(R.id.synopsis_text_view);
mediaName.setText(name);
/* create new DownloadImageTask class for displaying image from url. Picasso API can be used instead if wanted to view picture as well.
this needs to be used since the app will crash due to nature of threading, so AsyncTask is implemented.
*/
new DownloadImageTask((ImageView) getActivity().findViewById(R.id.poster)).execute(urlString);
} catch (JSONException jsone) {
Log.wtf("Json Import problems", jsone);
}
}
});
}
}
Edit:
package com.walkindeep.teammanagerpreview;
import android.content.Context;
import android.os.Bundle;
import android.support.design.widget.BottomSheetBehavior;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.Toolbar;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.Toast;
import com.dexafree.materialList.card.Card;
import com.dexafree.materialList.card.CardProvider;
import com.dexafree.materialList.card.OnActionClickListener;
import com.dexafree.materialList.card.action.TextViewAction;
import com.dexafree.materialList.listeners.OnDismissCallback;
import com.dexafree.materialList.view.MaterialListView;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
public class MyTaskActivity extends NavigationActivity {
private Context mContext = this;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/*全局导航栏*/
LayoutInflater inflater = (LayoutInflater) this
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View contentView = inflater.inflate(R.layout.activity_task, null, false);
drawer.addView(contentView, 0);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.floatingActionButtionTask);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
View bottomSheet = findViewById(R.id.bottom_sheet);
BottomSheetBehavior bottomSheetBehavior = BottomSheetBehavior.from(bottomSheet);
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
}
});
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
/*cardView*/
// initCard();
final User user = User.init("xxx", "xxx");
updateTask(user);
/*下滑刷新*/
final SwipeRefreshLayout swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.SwipeRefreshLayout);
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
updateTask(user, swipeRefreshLayout);
}
});
}
/*更新任务数据*/
private void updateTask(User user, SwipeRefreshLayout swipeRefreshLayout) {
DataHandler dataHandler = new DataHandler();
dataHandler.getData("issues.json?assigned_to_id=me" + "&status_id=1", this, user);
swipeRefreshLayout.setRefreshing(false);
}
/*更新任务数据*/
private void updateTask(User user) {
DataHandler dataHandler = new DataHandler();
dataHandler.getData("issues.json?assigned_to_id=me" + "&status_id=1", this, user);
}
private Card[] jsonToCards(JSONObject userIssuesJSONObjectTemp) {
JSONArray userIssuesJSONArray = null;
try {
userIssuesJSONArray = userIssuesJSONObjectTemp.getJSONArray("issues");
} catch (JSONException e) {
e.printStackTrace();
}
List<Card> cards = new ArrayList<>();
/*用于存储所有issue的list*/
List<Issue> issueList = Issue.getIssueList();
issueList.clear();
for (int i = 0; i < userIssuesJSONArray.length(); i++) {
try {
/*创建issue类*/
Issue issue = new Issue(userIssuesJSONArray.getJSONObject(i).getString("subject"), userIssuesJSONArray.getJSONObject(i).getString("description"), userIssuesJSONArray.getJSONObject(i).getInt("id"));
issueList.add(issue);
Card card = new Card.Builder(this)
.withProvider(new CardProvider())
.setLayout(R.layout.material_basic_buttons_card)
.setTitle(issue.getSubject())
.setDescription(issue.getDescription())
.addAction(R.id.left_text_button, new TextViewAction(this)
.setText("按钮1")
.setTextResourceColor(R.color.black_button)
.setListener(new OnActionClickListener() {
#Override
public void onActionClicked(View view, Card card) {
Toast.makeText(mContext, "You have pressed the left button", Toast.LENGTH_SHORT).show();
}
}))
.addAction(R.id.right_text_button, new TextViewAction(this)
.setText("按钮2")
.setTextResourceColor(R.color.accent_material_dark)
.setListener(new OnActionClickListener() {
#Override
public void onActionClicked(View view, Card card) {
Toast.makeText(mContext, "You have pressed the right button", Toast.LENGTH_SHORT).show();
}
}))
.endConfig()
.build();
card.setTag(issue);//设置卡片和issue关联
cards.add(card);
} catch (JSONException e) {
e.printStackTrace();
}
}
return cards.toArray(new Card[cards.size()]);
}
public void setCardsToUI(Card[] cards) {
final MaterialListView mListView = (MaterialListView) findViewById(R.id.material_listview);
mListView.getAdapter().clearAll();
for (int i = 0; i < cards.length; i++) {
mListView.getAdapter().add(cards[i]);
/*设置卡片可以滑动删除*/
cards[i].setDismissible(true);
}
/*设置滑动删除操作*/
mListView.setOnDismissCallback(new OnDismissCallback() {
public void onDismiss(final Card card, final int position) {
Snackbar.make(mListView, "已标记完成", Snackbar.LENGTH_LONG)
.setCallback(new Snackbar.Callback() {
#Override
public void onDismissed(Snackbar snackbar, int event) {
if (event == DISMISS_EVENT_ACTION) {//do nothing but recover card
mListView.getAdapter().add(position, card);
} else {
Issue issue = (Issue) card.getTag();
issue.setStatusid(3);
issue.pushStatusName(mContext);
List<Issue> issueList = Issue.getIssueList();
}
}
})
.setAction("撤销", new View.OnClickListener() {
#Override
public void onClick(View v) {
}
})
.show();
}
});
}
class DataHandler extends AbstractDataQuery {
#Override
protected void work(JSONObject userIssuesJSONObject) {
Card[] cards = jsonToCards(userIssuesJSONObject);
setCardsToUI(cards);
}
}
}
When click the floating action button "+", the bottomsheet show up like this:
Here is the activity_task.xml file:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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:fitsSystemWindows="true"
tools:context=".MyTaskActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="#style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<include layout="#layout/content_task" />
</LinearLayout>
<ScrollView
android:layout_width="match_parent"
android:id="#+id/bottom_sheet"
android:layout_height="wrap_content"
app:layout_behavior="android.support.design.widget.BottomSheetBehavior">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<Button
android:id="#+id/buildProjectButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/buildProject" />
<Button
android:id="#+id/buildTaskButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/buildTask" />
</LinearLayout>
</ScrollView>
<android.support.design.widget.FloatingActionButton
android:id="#+id/floatingActionButtionTask"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="#dimen/fab_margin"
android:src="#android:drawable/ic_input_add" />
</android.support.design.widget.CoordinatorLayout>
Everything seems OK, but when I click above the bottomsheet, it doesn't disappear totally as I expect:
What's wrong?
"By attaching a BottomSheetBehavior to a child View of a CoordinatorLayout (i.e., adding app:layout_behavior=”android.support.design.widget.BottomSheetBehavior”), you’ll automatically get the appropriate touch detection to transition between five state...".Try changing your Linear Layout to Frame Layout will do.
Try to use like this.
<FrameLayout
android:id="#+id/bottom_sheet"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#ff0000"
app:behavior_hideable="true"
app:layout_behavior="android.support.design.widget.BottomSheetBehavior">
<Button
android:id="#+id/buildProjectButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/buildProject" />
<Button
android:id="#+id/buildTaskButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/buildTask" />
</FrameLayout>
Modify your code as this.
View bottomSheet = findViewById(R.id.bottom_sheet);
BottomSheetBehavior bottomSheetBehavior = BottomSheetBehavior.from(bottomSheet);
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
bottomSheetBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
#Override
public void onStateChanged(#NonNull View bottomSheet, int newState) {
// React to state change
Log.e("onStateChanged", "onStateChanged:" + newState);
if (newState == BottomSheetBehavior.STATE_EXPANDED) {
// Hide your state here.
}
}
#Override
public void onSlide(#NonNull View bottomSheet, float slideOffset) {
// React to dragging events
Log.e("onSlide", "onSlide");
}
});
EDIT 1:
Bottom sheets behavior is not hideable by default. You need to add this.
bottomSheetBehavior.setHideable(true);
You are using a Persistent bottom sheet, this type of bottom sheet responds mainly to drag events i.e. you have to close it by dragging it down. If you want a bottom sheet that responds to clicking outside the dialog, consider Modal bottom sheet.
Alternatively, you can also use the fab to toggle the state of the bottom sheet i.e onClick of the fab it should expand the sheet if collapsed or collapse it if expanded.