I have two array lists, one for employees, another for their availabilities. The arrays are of different size. I don't see the problem with that when I'm using the array of the larger size in getItemCount():
#Override
public int getItemCount() {
return allEmployees.size();
}
I set recycler view to get all employee items, however my availability is a shorter list. If I have 6 availability's and 12 employees everything goes smooth on the first page as it only shows the 6 employees. But when I scroll down it will crash as there is a 7th employee but no 7th availability.
Recycler View :
public class RecycleViewAdapter extends RecyclerView.Adapter<RecycleViewAdapter.MyViewHolder> {
List<EmployeeModel> allEmployees;
List<AvailabilityModel> allAvailabilitys;
Context context;
public RecycleViewAdapter(List<EmployeeModel> allEmployees, List<AvailabilityModel> allAvailabilitys, Context context) {
this.allAvailabilitys = allAvailabilitys;
this.allEmployees = allEmployees;
this.context = context;
}
#NonNull
#Override
public MyViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_view_employee, parent, false);
MyViewHolder holder = new MyViewHolder(view);
return holder;
}
#Override
public void onBindViewHolder(#NonNull MyViewHolder holder, int position) {
AvailabilityModel available = allAvailabilitys.get(position);
EmployeeModel employee = allEmployees.get(position);
holder.employeeID.setText(String.valueOf(allEmployees.get(position).getEID()));
holder.firstName.setText(allEmployees.get(position).getfName());
holder.lastName.setText(allEmployees.get(position).getlName());
//holder.position = position;
holder.employee = employee;
holder.editButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(context, EditEmployee.class);
intent.putExtra("Editing", employee);
context.startActivity(intent);
}
});
holder.availabilityButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(context, availability_screen_code.class);
intent.putExtra("Available", employee);
intent.putExtra("Days", available);
context.startActivity(intent);
}
});
holder.parentLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(context, ViewEmployee.class);
intent.putExtra("Viewing", employee);
context.startActivity(intent);
}
});
}
#Override
public int getItemCount() {
return allEmployees.size();
}
public class MyViewHolder extends RecyclerView.ViewHolder{
TextView firstName;
TextView lastName;
TextView employeeID;
int position;
ImageButton editButton;
ImageButton availabilityButton;
EmployeeModel employee;
ConstraintLayout parentLayout;
public MyViewHolder(#NonNull View itemView) {
super(itemView);
firstName = itemView.findViewById(R.id.fNameView);
lastName = itemView.findViewById(R.id.lNameView);
employeeID = itemView.findViewById(R.id.eIDView);
editButton = itemView.findViewById(R.id.imageButton2);
availabilityButton = itemView.findViewById(R.id.imageButton4);
parentLayout = itemView.findViewById(R.id.parentLayout);
}
}
}
Where I'm using the position:
public class availability_screen_code extends AppCompatActivity implements AdapterView.OnItemSelectedListener {
private Spinner mondaySpinner, tuesdaySpinner, wednesdaySpinner, thursdaySpinner, fridaySpinner, saturdaySpinner, sundaySpinner;
// private String mondayChoice, tuesdayChoice, wednesdayChoice, thursdayChoice, fridayChoice, saturdayChoice, sundayChoice;
// private static final boolean [] choices = new boolean[6];
private ImageButton confirmation;
EmployeeDBAssist employeeDB;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.availability_screen);
mondaySpinner = findViewById(R.id.mondaySpinner);
tuesdaySpinner = findViewById(R.id.tuesdaySpinner);
wednesdaySpinner = findViewById(R.id.wednesdaySpinner);
thursdaySpinner = findViewById(R.id.thursdaySpinner);
fridaySpinner = findViewById(R.id.fridaySpinner);
saturdaySpinner = findViewById(R.id.saturdaySpinner);
sundaySpinner = findViewById(R.id.sundaySpinner);
confirmation = findViewById(R.id.confirm);
//this is linked to the recycler which gets an entire list of availability!
Bundle bundle = getIntent().getExtras();
AvailabilityModel available = (AvailabilityModel) getIntent().getSerializableExtra("Days");
EmployeeModel employee = (EmployeeModel) getIntent().getSerializableExtra("Available"); //this is where im using it
employeeDB = new EmployeeDBAssist(availability_screen_code.this);
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this, R.array.availableTimes, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
//monday
mondaySpinner.setAdapter(adapter);
mondaySpinner.setOnItemSelectedListener(this);
String availableString = available.getMonday();
mondaySpinner.setSelection(getIndex(mondaySpinner, availableString));
Toast.makeText(this, availableString, Toast.LENGTH_SHORT).show();
//tuesday
tuesdaySpinner.setAdapter(adapter);
tuesdaySpinner.setOnItemSelectedListener(this);
//wednesday
wednesdaySpinner.setAdapter(adapter);
wednesdaySpinner.setOnItemSelectedListener(this);
//thursday
thursdaySpinner.setAdapter(adapter);
thursdaySpinner.setOnItemSelectedListener(this);
//friday
fridaySpinner.setAdapter(adapter);
fridaySpinner.setOnItemSelectedListener(this);
//saturday
saturdaySpinner.setAdapter(adapter);
saturdaySpinner.setOnItemSelectedListener(this);
//sunday
sundaySpinner.setAdapter(adapter);
sundaySpinner.setOnItemSelectedListener(this);
confirmation.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
AvailabilityModel availabilityModel;
try{
availabilityModel = new AvailabilityModel(-1, employee.getEID(), mondaySpinner.getSelectedItem().toString(), tuesdaySpinner.getSelectedItem().toString(), wednesdaySpinner.getSelectedItem().toString(), thursdaySpinner.getSelectedItem().toString(), fridaySpinner.getSelectedItem().toString(), saturdaySpinner.getSelectedItem().toString(), sundaySpinner.getSelectedItem().toString());
EmployeeDBAssist employeeDBAssist = new EmployeeDBAssist(availability_screen_code.this);
employeeDBAssist.updateAvailability(employee.getEID(),mondaySpinner.getSelectedItem().toString(), tuesdaySpinner.getSelectedItem().toString(), wednesdaySpinner.getSelectedItem().toString(), thursdaySpinner.getSelectedItem().toString(), fridaySpinner.getSelectedItem().toString(), saturdaySpinner.getSelectedItem().toString(), sundaySpinner.getSelectedItem().toString());
Toast.makeText(availability_screen_code.this, String.valueOf(employee.getEID()) + " " + mondaySpinner.getSelectedItem().toString()+ " " + tuesdaySpinner.getSelectedItem().toString()+ " " + wednesdaySpinner.getSelectedItem().toString()+ " " + thursdaySpinner.getSelectedItem().toString()+ " " + fridaySpinner.getSelectedItem().toString()+ " " + saturdaySpinner.getSelectedItem().toString()+ " " + sundaySpinner.getSelectedItem().toString(), Toast.LENGTH_SHORT).show();
boolean success = employeeDBAssist.addAvailability(availabilityModel);
}
catch (Exception e){
Toast.makeText(availability_screen_code.this, "Error Setting Availability", Toast.LENGTH_SHORT).show();
}
Intent i = new Intent(availability_screen_code.this,activity_main_code.class);
startActivity(i);
Toast.makeText(availability_screen_code.this, String.valueOf(employee.getEID()) + " " + mondaySpinner.getSelectedItem().toString()+ " " + tuesdaySpinner.getSelectedItem().toString()+ " " + wednesdaySpinner.getSelectedItem().toString()+ " " + thursdaySpinner.getSelectedItem().toString()+ " " + fridaySpinner.getSelectedItem().toString()+ " " + saturdaySpinner.getSelectedItem().toString()+ " " + sundaySpinner.getSelectedItem().toString(), Toast.LENGTH_SHORT).show();
}
});
}
availability table has 2 values and employees 7. In getItemCount I'm using the size of my employee table. However, I need to get the position of my availability so that I can use it in another class. It will only work for the first two entries. Once I scroll down it throws :
java.lang.IndexOutOfBoundsException: Index: 2, Size: 2
Adding an availability for every employee would defeat the purpose of my project. How to solve this with the use of two separate arrays of different size?
You can check whether the corresponding AvailabilityModel exists before calling List#get(), if not, directly assign available to null. At the same time, you also need to perform a null check in intent.putExtra("Available", employee);.
Update I fixed the problem using a little bit of what #perfect puzzle said here's the solution
Here's the recyclerViewAdapter updated code
I first created an if statement to check whether the pointer was below the size of the availability list allAvailabilitys.size(), then created a null check within the intent.putExtra field as per #perfectpuzzle instruction
#Override
public void onBindViewHolder(#NonNull MyViewHolder holder, int position) {
EmployeeModel employee;
AvailabilityModel available = null;
if(position < allAvailabilitys.size()){
available = allAvailabilitys.get(position);
employee = allEmployees.get(position);
holder.employeeID.setText(String.valueOf(allEmployees.get(position).getEID()));
holder.firstName.setText(allEmployees.get(position).getfName());
holder.lastName.setText(allEmployees.get(position).getlName());
holder.employee = employee;
} else{
employee = allEmployees.get(position);
holder.employeeID.setText(String.valueOf(allEmployees.get(position).getEID()));
holder.firstName.setText(allEmployees.get(position).getfName());
holder.lastName.setText(allEmployees.get(position).getlName());
holder.employee = employee;
}
EmployeeModel finalEmployee = employee;
holder.editButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(context, EditEmployee.class);
intent.putExtra("Editing", finalEmployee);
context.startActivity(intent);
}
});
EmployeeModel finalEmployee1 = employee;
AvailabilityModel finalAvailable = available;
holder.availabilityButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(context, availability_screen_code.class);
intent.putExtra("Available", finalEmployee1);
if(finalAvailable!= null){
intent.putExtra("Days", finalAvailable);
}
context.startActivity(intent);
}
});
EmployeeModel finalEmployee2 = employee;
holder.parentLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(context, ViewEmployee.class);
intent.putExtra("Viewing", finalEmployee2);
context.startActivity(intent);
}
});
}
}
Updated use of position
here I also check if available is null and I also created a function to translate a null into the default String used in my spinner.
Bundle bundle = getIntent().getExtras();
AvailabilityModel available = (AvailabilityModel) getIntent().getSerializableExtra("Days");
EmployeeModel employee = (EmployeeModel) getIntent().getSerializableExtra("Available");
employeeDB = new EmployeeDBAssist(availability_screen_code.this);
//setting elements in spinner
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this, R.array.availableTimes, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
//monday
mondaySpinner.setAdapter(adapter);
//tuesday
tuesdaySpinner.setAdapter(adapter);
//wednesday
wednesdaySpinner.setAdapter(adapter);
//thursday
thursdaySpinner.setAdapter(adapter);
//friday
fridaySpinner.setAdapter(adapter);
//saturday
saturdaySpinner.setAdapter(adapter);
//sunday
sundaySpinner.setAdapter(adapter);
if(available != null){
mondayChoice = getAvailableDay(available.getMonday());
mondaySpinner.setSelection(getIndex(mondaySpinner, mondayChoice));
tuesdayChoice = getAvailableDay(available.getTuesday());
tuesdaySpinner.setSelection(getIndex(tuesdaySpinner, tuesdayChoice));
wednesdayChoice = getAvailableDay(available.getWednesday());
wednesdaySpinner.setSelection(getIndex(wednesdaySpinner, wednesdayChoice));
thursdayChoice = getAvailableDay(available.getThursday());
thursdaySpinner.setSelection(getIndex(thursdaySpinner, thursdayChoice));
fridayChoice = getAvailableDay(available.getFriday());
fridaySpinner.setSelection(getIndex(fridaySpinner, fridayChoice));
saturdayChoice = getAvailableDay(available.getSaturday());
saturdaySpinner.setSelection(getIndex(saturdaySpinner, saturdayChoice));
sundayChoice = getAvailableDay(available.getSunday());
sundaySpinner.setSelection(getIndex(sundaySpinner, sundayChoice));
}
else{
Toast.makeText(this, "null field", Toast.LENGTH_SHORT).show();
}
}
Hope this can help someone out.
Related
I have a MainAtivity which has some EditText and 2 button. Save button will save user input to ListView and List button to show ListView (which I display in second activity).
Is there anyway to collect data from multiple inputs then pass it to other activity. And after get that data how to combine it to a List item.
Please show me some code and explain cause I'm a beginner.
I have read some post and they suggest use startActivityForResult, intent, bundles but I still don't understand.
This is my Main class:
public class MainActivity extends AppCompatActivity {
String str, gender, vaccine, date;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button okay = (Button) findViewById(R.id.btnOk);
Button list = (Button) findViewById(R.id.btnList);
EditText name = (EditText) findViewById(R.id.inputName);
EditText address = (EditText) findViewById(R.id.inputAdd);
EditText phone = (EditText) findViewById(R.id.inputPhone);
RadioGroup radioGroup = (RadioGroup) findViewById(R.id.radioGroup);
RadioButton female = (RadioButton) findViewById(R.id.inputFemale);
RadioButton male = (RadioButton) findViewById(R.id.inputMale);
CheckBox first = (CheckBox)findViewById(R.id.inputFirst);
CheckBox second = (CheckBox)findViewById(R.id.inputSecond);
CheckBox third = (CheckBox)findViewById(R.id.inputThird);
EditText datefirst = (EditText) findViewById(R.id.dateFirst);
EditText datesecond = (EditText) findViewById(R.id.dateSecond);
EditText datethird = (EditText) findViewById(R.id.dateThird);
TextView result = (TextView)findViewById(R.id.textResult);
okay.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(female.isChecked()) gender = female.getText().toString();
if(male.isChecked()) gender = male.getText().toString();
if(first.isChecked()) {
vaccine = first.getText().toString();
date = datefirst.getText().toString();
}
if(second.isChecked()) {
vaccine = second.getText().toString();
date = datesecond.getText().toString();
}
if(third.isChecked()) {
vaccine = third.getText().toString();
date = datethird.getText().toString();
}
str = name.getText().toString() + "\n" + address.getText().toString() + "\n" + phone.getText().toString() + "\n" +
gender + "\n" + vaccine + "\n" + date;
result.setText(str);
Toast.makeText(getApplicationContext(),result.getText().toString(),Toast.LENGTH_SHORT).show();
Intent intent = new Intent(MainActivity.this, PersonView.class);
intent.putExtra("NAME",name.getText().toString());
startActivity(intent);
}
});
list.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(MainActivity.this, PersonView.class);
startActivity(intent);
}
});
}
}
This is my ListView class:
public class PersonView extends AppCompatActivity {
ArrayList<Person> listPerson;
PersonListViewAdapter personListViewAdapter;
ListView listViewPerson;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list);
Intent intent = getIntent();
String message = intent.getStringExtra("NAME");
Button back = (Button) findViewById(R.id.btnBack);
back.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(PersonView.this, MainActivity.class);
//startActivityForResult(intent,2);
}
});
listPerson = new ArrayList<>();
listPerson.add(new Person("Lieu Mai","25 Mac Dinh Chi", "0786867073", "female","3 injection", "24/07/2000"));
personListViewAdapter = new PersonListViewAdapter(listPerson);
listViewPerson = findViewById(R.id.listPerson);
listViewPerson.setAdapter(personListViewAdapter);
}
class Person {
String name, address, phone, gender, vaccine, date;
public Person( String name, String address, String phone, String gender, String vaccine, String date) {
this.name = name;
this.address = address;
this.phone = phone;
this.gender = gender;
this.vaccine = vaccine;
this.date = date;
}
}
class PersonListViewAdapter extends BaseAdapter {
final ArrayList<Person> listPerson;
PersonListViewAdapter(ArrayList<Person> listPerson) {
this.listPerson = listPerson;
}
#Override
public int getCount() {
return listPerson.size();
}
#Override
public Object getItem(int position) {
return listPerson.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View viewPerson;
if (convertView == null) {
viewPerson = View.inflate(parent.getContext(), R.layout.person_view, null);
} else viewPerson = convertView;
Person person = (Person) getItem(position);
((TextView) viewPerson.findViewById(R.id.txtName)).setText(String.format("Name: %s", person.name));
((TextView) viewPerson.findViewById(R.id.txtAddress)).setText(String.format("Address : %s", person.address));
((TextView) viewPerson.findViewById(R.id.txtPhone)).setText(String.format("Phone number: %s", person.phone));
((TextView) viewPerson.findViewById(R.id.txtGender)).setText(String.format("Gender: %s", person.gender));
((TextView) viewPerson.findViewById(R.id.txtVaccine)).setText(String.format("Vaccine: %s", person.vaccine));
((TextView) viewPerson.findViewById(R.id.txtDate)).setText(String.format("Date: %s", person.date));
return viewPerson;
}
}
}
You should look into the Singleton pattern. It is very simple as there is no external DB. What it essentially is a class that manages the data and lets other classes and activities use the data while not allowing duplication.
You have a model Person
public class Person {
private String name;
public String address;
...
constructors and getters and setters
Create a class PersonsSingelton something like this.
public class PersonManagerSingleton {
private PersonManagerSingleton() {
loadPersonsDataSet();
}
private static PersonManagerSingleton instance = null;
public static PersonManagerSingleton getInstance() {
// if there is a instance already created use that instance of create new instance
// instance created in MainActivity and you try to create a new instance in Details
// should not happen as that will cause data duplication.
if (instance == null) {
instance = new PersonManagerSingleton();
}
return instance;
}
private ArrayList<Person> personList = new ArrayList<Person>();
private void loadPersonsDataSet() {
this.personList.add(new Person(...));
this.personList.add(new Person(...));
this.personList.add(new Person(...));
this.personList.add(new Person(...));
}
public ArrayList<Person> getpersonList() {
return personList;
}
public Person getPersonByID(int PersonNumber) {
for (int i = 0; i < this.personList.size(); i++) {
Person curPerson = this.personList.get(i);
if (curPerson.getNumber() == PersonNumber) {
return curPerson;
}
}
return null;
}
// methods for adding a new person used in Activity with the form.
// other methods ...
}
This would be like a state in React. of the State Manager.
Your person adapter constructor has to accept an ArrayList<Person> listPerson. So modify the activity passing the data to pass only the position of the ListView clicked. You need to modify your Adapter for that.
Use the Singleton created to access the data.
PersonManagerSingleton personSingelton = PersonManagerSingleton.getInstance();
ArrayList<Person> listPerson = personSingelton.getPersonList();
PersonAdapter Person = new PersonAdapter(listPerson);
So now only things left is to modify the Persons adapter to pass position using Intent and nothing else. and then you can use the instance of Singleton in other files to access the data using the listPerson.get(position) and using getters and setters.
Link to a project like this.
https://github.com/smitgabani/anroid_apps_using_java/tree/main/pokemon_app
I have some error in android studio.
When i try to add symbol ('*') to special item, it also add the symbol to the item that placed in +14 from the first.
I will glad if someone have solution for this problem.
For more information you can check this link, where i describe the problem.
https://youtu.be/CJFkt-Cck1A
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.MyViewHolder> {
private static final String TAG = "RecyclerViewAdapter";
private Context context;
private List<WorkDayItem> workDayItemList;
//Complete
public RecyclerViewAdapter(Context context, List<WorkDayItem> workDayItemList) {
this.context = context;
this.workDayItemList = workDayItemList;
}
//Complete
//Here we create view- itemWorkday and inflate it by layout- item_one_work_day
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemWorkDay = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_one_work_day, parent, false);
MyViewHolder myViewHolder = new MyViewHolder(itemWorkDay);
return myViewHolder;
}
#Override
public void onBindViewHolder(final MyViewHolder holder, int position) {
Log.d(TAG, "onBindViewHolder: called." + (position + 1) + "\n" + workDayItemList.get(position).toString());
final WorkDayItem workDayItem = workDayItemList.get(position);
String dateStart = (String) DateFormat.format("dd.MM", workDayItem.getDateStart());
String timeStart = (String) DateFormat.format("HH:mm", workDayItem.getDateStart());
String timeEnd = (String) DateFormat.format("HH:mm", workDayItem.getDateEnd());
//Convert data from firebase String format to int hours and minutes format.
Double convertingDataFromFirebase;
try {
convertingDataFromFirebase = Double.parseDouble(new DecimalFormat("##.##").format(workDayItem.getCount_hours()));
} catch (NumberFormatException e) {
convertingDataFromFirebase = 0.0;
}
int hours = convertingDataFromFirebase.intValue();
convertingDataFromFirebase = (convertingDataFromFirebase - convertingDataFromFirebase.intValue()) * 60;
int minutes = convertingDataFromFirebase.intValue();
//Check if current item have description
if (workDayItemList.get(position).getDesc().length() > 2) {
Log.i(TAG, "TESTER: desc dote added");
holder.doteOfDesc.setVisibility(View.VISIBLE);
}
holder.dayPosition.setText((position + 1) + "");
holder.dateStart.setText(dateStart);
holder.timeStart.setText(timeStart);
holder.timeEnd.setText(timeEnd);
holder.countOfHours.setText(hours + ":" + minutes);
//On click on current hold open alert dialog with some functions
holder.parentLayout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
initializeAlertDialogForItem(workDayItem, holder);
}
});
}
//initialize data about current work day and have button for changing information
private void initializeAlertDialogForItem(final WorkDayItem workDayItem, final MyViewHolder holder) {
//Initialize alert dialog
final AlertDialog alertDialog = new AlertDialog.Builder(context).create();
View itemWork = LayoutInflater.from(context)
.inflate(R.layout.ad_item_desc, null, false);
alertDialog.setView(itemWork);
alertDialog.show();
//initialize alert dialog buttons and views
final ImageButton change = alertDialog.findViewById(R.id.itemAD_Edit);
final ImageButton delete = alertDialog.findViewById(R.id.itemAD_Delete);
TextView description = alertDialog.findViewById(R.id.itemADDescription);
TextView date = alertDialog.findViewById(R.id.itemADDate);
TextView from = alertDialog.findViewById(R.id.itemADFrom);
TextView to = alertDialog.findViewById(R.id.itemADTO);
String timeStart = (String) (DateFormat.format("HH:mm", workDayItem.getDateStart()));
String timeEnd = (String) (DateFormat.format("HH:mm", workDayItem.getDateEnd()));
String dateStart = (String) (DateFormat.format("dd.MM.yyyy", workDayItem.getDateStart()));
date.setText(dateStart);
from.setText(timeStart);
to.setText(timeEnd);
description.setText(workDayItem.getDesc());
//Change button
change.setOnClickListener(new View.OnClickListener() {
#RequiresApi(api = Build.VERSION_CODES.M)
#Override
public void onClick(View v) {
AlertDialogReport userReport = new AlertDialogReport(context, "replace-remove", workDayItem);
userReport.initializeAlertDialog();
alertDialog.dismiss();
}
});
delete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Delete data from firebase
Login.fc.databaseReference.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot snapshot : dataSnapshot.getChildren()) {
String itemTime = "" + workDayItem.getDateStart().getTime();
String firebaseTime = "" + snapshot.child("dateStart").child("time").getValue();
if (itemTime.equals(firebaseTime)) {
Login.fc.databaseReference.child(snapshot.getKey()).removeValue();
}
}
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
//Delete data from SqLiteDatabase
MySQLDataBase dataBase = new MySQLDataBase(context);
dataBase.deleteItem(workDayItem);
//Finish with alert dialog and notify user
alertDialog.dismiss();
Toast.makeText(context, R.string.item_deleted, Toast.LENGTH_SHORT).show();
holder.parentLayout.removeAllViews();
}
});
}
//Complete
#Override
public int getItemCount() {
return workDayItemList.size();
}
//Complete
//Here we catch our view and getting reference between view and our objects
public class MyViewHolder extends RecyclerView.ViewHolder {
private LinearLayout parentLayout;
private TextView doteOfDesc, dayPosition, dateStart, timeStart, timeEnd, countOfHours;
public MyViewHolder(View view) {
super(view);
doteOfDesc = view.findViewById(R.id.itemDote);
dayPosition = view.findViewById(R.id.itemDayPosition);
dateStart = view.findViewById(R.id.itemDateStart);
timeStart = view.findViewById(R.id.itemStartHour);
timeEnd = view.findViewById(R.id.itemEndHour);
countOfHours = view.findViewById(R.id.itemCountOfHours);
parentLayout = view.findViewById(R.id.itemWorkDay);
}
}
}
Try adding this:
//Check if current item have description
if (workDayItemList.get(position).getDesc().length() > 2) {
Log.i(TAG, "TESTER: desc dote added");
holder.doteOfDesc.setVisibility(View.VISIBLE);
}
else if( workDayItemList.get(position).getDesc().length() < 2
&& holder.doteOfDesc.getVisibility()== View.VISIBLE ){
holder.doteOfDesc.setVisibility(View.GONE);
}
The reason why this is happening is that RecyclerView creates as many ViewHolders as its needed to cover a whole screen plus few extra ( 12 in your case) then reuses them via rebinding values to views. And you set doteOfDescto View.VISIBLE in 2. ViewHolder, but never set it back to View.GONE, thats why every time that ViewHolder is reused it will have doteOfDesc visible.
The Prettier version:
Boolean hasDescription = workDayItemList.get(position).getDesc().length() > 2;
holder.doteOfDesc.setVisibility( hasDescription ? View.VISIBLE : View.GONE);
I was working with android project these days, and It will finish soon, but I got stuck in my project. First, I want to create search activity which will be used for searching movies. The searching activity runs well, but whenever it comes to adding the selected movie, it shown me the error code below:
java.lang.NullPointerException: Attempt to invoke virtual method 'void com.example.idstream.pojo.Movies.setTitle(java.lang.String)' on a null object reference
at com.example.idstream.search.MoviesDetailActivity.addFavorite(MoviesDetailActivity.java:96)
at com.example.idstream.search.MoviesDetailActivity.access$100(MoviesDetailActivity.java:19)
at com.example.idstream.search.MoviesDetailActivity$1.onClick(MoviesDetailActivity.java:78)
This code has an error in this area:
Movies movies = getIntent().getParcelableExtra(EXTRA_TITLE);
movies.setTitle(getIntent().getStringExtra(EXTRA_TITLE));
movies.setRelease_info(getIntent().getStringExtra(EXTRA_RELEASE));
movies.setLanguage(getIntent().getStringExtra(EXTRA_LANGUAGE));
movies.setDescription(getIntent().getStringExtra(EXTRA_OVERVIEW));
movies.setPhotos(getIntent().getStringExtra(EXTRA_PHOTOS));
I've tried to add the selected movie to database in other activity, but it didn't mention any error. But when I tried to save the selected movie to database, it turns out an error. I also tried to send it to a toast, which I wanna make sure whether the value that I sent was successfully retrieved. The toast is successfully get the data.
Here is my SearchFragment.java:
public class SearchMovieFragment extends Fragment implements LoaderManager.LoaderCallbacks<ArrayList<Movies>> {
ListView lvMovieItems;
EditText txtTitleMovieInput;
ImageView imgMoviesSearch;
Button btnSearchMovie;
AdaptersMovie adaptersMovie;
MovieHelper movieHelper;
Boolean act = true;
Boolean insert = true;
Boolean delete = true;
private View mView;
public SearchMovieFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
mView = inflater.inflate(R.layout.fragment_search_movie, container, false);
txtTitleMovieInput = (EditText)mView.findViewById(R.id.txtMovieTitle);
String mTitles = txtTitleMovieInput.getText().toString();
Bundle bundle = new Bundle();
bundle.putString(EXTRA_MOVIE, mTitles);
imgMoviesSearch = (ImageView)mView.findViewById(R.id.imgMovies);
btnSearchMovie = (Button) mView.findViewById(R.id.btn_search);
btnSearchMovie.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String mTitleMovie = txtTitleMovieInput.getText().toString();
if(TextUtils.isEmpty(mTitleMovie)){
return;
}
Bundle bundle = new Bundle();
bundle.putString(EXTRA_MOVIE, mTitleMovie);
getLoaderManager().restartLoader(0, bundle, SearchMovieFragment.this);
}
});
getLoaderManager().initLoader(0, bundle, SearchMovieFragment.this);
adaptersMovie = new AdaptersMovie(getActivity());
adaptersMovie.notifyDataSetChanged();
lvMovieItems = (ListView)mView.findViewById(R.id.listMovies);
lvMovieItems.setAdapter(adaptersMovie);
lvMovieItems.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Movies item = (Movies)parent.getItemAtPosition(position);
Intent intent = new Intent(getActivity(), MoviesDetailActivity.class);
intent.putExtra(MoviesDetailActivity.EXTRA_MOVIE, item.getTitle());
intent.putExtra(MoviesDetailActivity.EXTRA_RELEASE, item.getRelease_info());
intent.putExtra(MoviesDetailActivity.EXTRA_LANGUAGE, item.getLanguage());
intent.putExtra(MoviesDetailActivity.EXTRA_OVERVIEW, item.getDescription());
intent.putExtra(MoviesDetailActivity.EXTRA_PHOTOS, item.getPhotos());
startActivity(intent);
}
});
return mView;
}
#NonNull
#Override
public Loader<ArrayList<Movies>> onCreateLoader(int id, #Nullable Bundle args) {
String temp = "";
if (args != null){
temp = args.getString(EXTRA_MOVIE);
}
return new MovieAsyncTaskLoader(getActivity(), temp);
}
#Override
public void onLoadFinished(#NonNull Loader<ArrayList<Movies>> loader, ArrayList<Movies> data) {
adaptersMovie.setData(data);
}
#Override
public void onLoaderReset(#NonNull Loader<ArrayList<Movies>> loader) {
adaptersMovie.setData(null);
}
}
My MoviesDetailActivity.java:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_movies_detail);
setTitle("Movie's Details");
tvTitles = findViewById(R.id.movieTitles);
tvReleased = findViewById(R.id.movieRelease);
tvLanguages = findViewById(R.id.movieLanguages);
tvDescription = findViewById(R.id.movieDescriptions);
imageMovies = findViewById(R.id.moviesImage);
progressBar = findViewById(R.id.progressMovie);
fav_moviesBtn = findViewById(R.id.fab_movie);
progressBar.setVisibility(View.VISIBLE);
String mvTitles = getIntent().getStringExtra(EXTRA_MOVIE);
String mvLanguages = getIntent().getStringExtra(EXTRA_LANGUAGE);
String mvOverview = getIntent().getStringExtra(EXTRA_OVERVIEW);
String mvRelease = getIntent().getStringExtra(EXTRA_RELEASE);
String mvPhotos = getIntent().getStringExtra(EXTRA_PHOTOS);
tvTitles.setText(mvTitles);
tvReleased.setText(mvRelease);
tvLanguages.setText(mvLanguages);
tvDescription.setText(mvOverview);
Glide.with(MoviesDetailActivity.this)
.load("https://image.tmdb.org/t/p/w185" + mvPhotos)
.placeholder(R.color.colorFreshOrange)
.dontAnimate()
.into(imageMovies);
movieHelper = new MovieHelper(MoviesDetailActivity.this);
movieHelper.open();
mMoviess = getIntent().getIntExtra(FAVOURITE,0);
fav_moviesBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!isAdd) {
addFavorite();
Toast.makeText(MoviesDetailActivity.this, "Berhasil Ditambahkan", Toast.LENGTH_LONG).show();
fav_moviesBtn.setImageResource(R.drawable.ic_launcher_fav_yes_24_foreground);
} else {
removeFavorite();
Toast.makeText(MoviesDetailActivity.this, "Berhasil Dihapuskan", Toast.LENGTH_LONG).show();
fav_moviesBtn.setImageResource(R.drawable.ic_launcher_fav_no_24_foreground);
}
}
});
progressBar.setVisibility(View.GONE);
}
private void addFavorite() {
Movies movies = getIntent().getParcelableExtra(EXTRA_TITLE);
movies.setTitle(getIntent().getStringExtra(EXTRA_TITLE));
movies.setRelease_info(getIntent().getStringExtra(EXTRA_RELEASE));
movies.setLanguage(getIntent().getStringExtra(EXTRA_LANGUAGE));
movies.setDescription(getIntent().getStringExtra(EXTRA_OVERVIEW));
movies.setPhotos(getIntent().getStringExtra(EXTRA_PHOTOS));
movieHelper.insertMovie(movies);
}
private void removeFavorite() {
Movies movies = new Movies();
movies.setTitle(getIntent().getStringExtra(EXTRA_TITLE));
movies.setRelease_info(getIntent().getStringExtra(EXTRA_RELEASE));
movies.setLanguage(getIntent().getStringExtra(EXTRA_LANGUAGE));
movies.setDescription(getIntent().getStringExtra(EXTRA_OVERVIEW));
movies.setPhotos(getIntent().getStringExtra(EXTRA_PHOTOS));
movieHelper.deleteMovie(getIntent().getStringExtra(EXTRA_MOVIE));
}
}
And this one is my MovieHelper.java:
public Boolean getOne(String name){
String querySingleRecord = "SELECT * FROM " + DATABASE_TABLE + " WHERE " +DatabaseContract.MovieColoumn.TITLE+ " " + " LIKE " +"'"+name+"'" ;
Cursor cursor = database.rawQuery(querySingleRecord,null);
cursor.moveToFirst();
Log.d("cursor", String.valueOf(cursor.getCount()));
if (cursor.getCount() > 0 ){
return true;
}else if(cursor.getCount() == 0){
return false;
}
return false;
}
public long insertMovie(Movies mMovies){
ContentValues args = new ContentValues();
args.put(IDS,mMovies.getId());
args.put(DatabaseContract.MovieColoumn.TITLE,mMovies.getTitle());
args.put(DatabaseContract.MovieColoumn.RELEASE_INFO,mMovies.getRelease_info());
args.put(DatabaseContract.MovieColoumn.LANGUAGE,mMovies.getLanguage());
args.put(DatabaseContract.MovieColoumn.DESCRIPTION,mMovies.getDescription());
args.put(DatabaseContract.MovieColoumn.PHOTOS,mMovies.getPhotos());
return database.insert(DATABASE_TABLE,null,args);
}
I believe the problem is here:
Movies movies = getIntent().getParcelableExtra(EXTRA_TITLE);
movies.setTitle(getIntent().getStringExtra(EXTRA_TITLE));
Notice that you're using the same EXTRA_TITLE for both.
I think that what's happening is that getParcelableExtra() is returning null, because the implementation of Bundle (the extras) will catch the ClassCastException:
// ...
try {
return (T) o;
} catch (ClassCastException e) {
typeWarning(key, o, "Parcelable", e);
return null;
}
And then you get a NullPointerException when you try to call setTitle().
Instead, create a new Movies instance yourself:
Movies movies = new Movies();
movies.setTitle(getIntent().getStringExtra(EXTRA_TITLE));
Alternatively, you could implement the Parcelable interface in your Movies class, and then you wouldn't have to bother adding all of its fields one by one.
I'm trying to make a laundry ordering application. I've made it to the order process, at the end of the order process, the user clicks the next button to checkout the ordered results, I have successfully made the checkout results, but what I made is still in one variable string. how to put the checkout results into an array variable so that I can post the results in the form of JSONArray?
HERE IS MY ORDER ACTIVITY CODE :
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_produk);
// menghubungkan variablel pada layout dan pada java
listProduk = (ListView)findViewById(R.id.list_produk);
swipeProduct = (SwipeRefreshLayout)findViewById(R.id.swipeProduct);
radioExpress = (RadioButton)findViewById(R.id.radio_express);
radioReguler = (RadioButton)findViewById(R.id.radio_regular);
tvTotal = (TextView)findViewById(R.id.total);
next = (Button)findViewById(R.id.button_next);
actionBar = getSupportActionBar();
laundry_id = getIntent().getStringExtra(TAG_LAUNDRY_ID);
// untuk mengisi data dari JSON ke dalam adapter
productAdapter = new CheckboxAdapter(this, (ArrayList<ProductModel>) productList, this);
listProduk.setAdapter(productAdapter);
listProduk.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
productAdapter.setCheckBox(position);
}
});
// menampilkan widget refresh
swipeProduct.setOnRefreshListener(this);
swipeProduct.post(new Runnable() {
#Override
public void run() {
swipeProduct.setRefreshing(true);
productList.clear();
tvTotal.setText(String.valueOf(0));
radioReguler.isChecked();
regular = true;
productAdapter.notifyDataSetChanged();
callProduct();
}
}
);
next.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String checkbox = "";
for (ProductModel hold : productAdapter.getAllData()) {
int total = Integer.parseInt(hold.getProduct_price())*(hold.getCountProduct());
if (hold.isCheckbox()) {
checkbox += "\n" + hold.getProduct_name() + " " + total;
}
}
if (!checkbox.isEmpty()) {
dipilih = checkbox;
} else {
dipilih = "Anda Belum Memilih Menu.";
}
formSubmit(dipilih);
}
});
}
private void formSubmit(String hasil){
AlertDialog.Builder dialog = new AlertDialog.Builder(this);
LayoutInflater inflater = getLayoutInflater();
View dialogView = inflater.inflate(R.layout.form_submit, null);
dialog.setView(dialogView);
dialog.setIcon(R.mipmap.ic_launcher);
dialog.setTitle("Menu Yang Dipilih");
dialog.setCancelable(true);
txtnamaProduk = (TextView) dialogView.findViewById(R.id.txtNama_produk);
txtnamaProduk.setText(hasil);
dialog.setNeutralButton("CLOSE", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
dialog.show();
}
AND HERE IS THE CODE OF THE RESULT :
next.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String checkbox = "";
for (ProductModel hold : productAdapter.getAllData()) {
int total = Integer.parseInt(hold.getProduct_price())*(hold.getCountProduct());
if (hold.isCheckbox()) {
checkbox += "\n" + hold.getProduct_name() + " " + total;
}
}
if (!checkbox.isEmpty()) {
dipilih = checkbox;
} else {
dipilih = "Anda Belum Memilih Menu.";
}
formSubmit(dipilih);
}
});
}
in my code above, I still use the variable checkbox to accommodate all the results of the order chosen by the user. how to put all the result into array variable so i can post to server as a JSONArray? Please help me to solve this problem. because i'm still a beginner in android.
HERE IS MY ADAPTER CODE IF NEEDED :
public class CheckboxAdapter extends BaseAdapter{
private Context context;
private ArrayList<ProductModel> productItems;
ProdukLaundry produk;
public CheckboxAdapter(Context context, ArrayList<ProductModel> items, ProdukLaundry produk) {
this.context = context;
this.productItems = items;
this.produk = produk;
}
#Override
public int getItemViewType(int position) {
return position;
}
#Override
public int getCount() {
return productItems.size();
}
#Override
public Object getItem(int position) {
return productItems.get(position);
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(final int position, View view, ViewGroup parent) {
final ViewHolder viewHolder;
final ProductModel items = productItems.get(position);
if(view == null) {
viewHolder = new ViewHolder();
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.list_produk, null, true);
viewHolder.checkBox = (CheckBox) view.findViewById(R.id.checkBox_productName);
viewHolder.decrease = (TextView) view.findViewById(R.id.decrease_product);
viewHolder.count = (TextView) view.findViewById(R.id.count_product);
viewHolder.increase = (TextView) view.findViewById(R.id.increase_product);
viewHolder.price = (TextView) view.findViewById(R.id.product_price);
view.setTag(viewHolder);
}else{
viewHolder = (ViewHolder) view.getTag();
}
viewHolder.checkBox.setText(items.getProduct_name());
viewHolder.price.setText(items.getProduct_price());
viewHolder.count.setText(String.valueOf(items.getCountProduct()));
//fungsi untuk set posisi textview + dan -
viewHolder.increase.setTag(R.integer.btn_plus_view, view);
viewHolder.increase.setTag(R.integer.btn_plus_pos, position);
viewHolder.decrease.setTag(R.integer.btn_minus_view, view);
viewHolder.decrease.setTag(R.integer.btn_minus_pos, position);
//fungsi untuk disable textview + dan - jika checkbox tidak di klik
viewHolder.decrease.setOnClickListener(null);
viewHolder.increase.setOnClickListener(null);
if(items.isCheckbox()){
viewHolder.checkBox.setChecked(true);
viewHolder.increase.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
View tempview = (View) viewHolder.increase.getTag(R.integer.btn_plus_view);
TextView tv = (TextView) tempview.findViewById(R.id.count_product);
Integer pos = (Integer) viewHolder.increase.getTag(R.integer.btn_plus_pos);
int countProduct = Integer.parseInt(tv.getText().toString()) + 1;
tv.setText(String.valueOf(countProduct));
productItems.get(pos).setCountProduct(countProduct);
produk.tambah(pos);
}
});
viewHolder.decrease.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
View tempview = (View)viewHolder.decrease.getTag(R.integer.btn_minus_view);
TextView tv = (TextView) tempview.findViewById(R.id.count_product);
Integer pos = (Integer) viewHolder.decrease.getTag(R.integer.btn_minus_pos);
int total = productItems.get(pos).getCountProduct();
if (total>0){
int countProduct = Integer.parseInt(tv.getText().toString()) - 1;
tv.setText(String.valueOf(countProduct));
productItems.get(pos).setCountProduct(countProduct);
produk.kurang(pos);
}
}
});
} else {
viewHolder.checkBox.setChecked(false);
//fungsi untuk reset jumlah harga dan produk pada checkbox
String count = viewHolder.count.getText().toString();
int jumlah = Integer.parseInt(count);
int harga = Integer.parseInt(productItems.get(position).getProduct_price());
int kurang = jumlah * harga;
viewHolder.count.setText("0");
productItems.get(position).setCountProduct(0);
produk.kurangCheckbox(kurang);
}
return view;
}
public ArrayList<ProductModel> getAllData(){
return productItems;
}
public void setCheckBox(int position){
ProductModel items = productItems.get(position);
items.setCheckbox(!items.isCheckbox());
notifyDataSetChanged();
}
static class ViewHolder{
TextView decrease, count, increase, price;
CheckBox checkBox;
}
}
just create getter setter method of Arraylist like below
CompleteOrder:-
public class CompleteOrder {
List<OrderItem> order_items;
public List<OrderItem> getOrder_items() {
return order_items;
}
public void setOrder_items(List<OrderItem> order_items) {
this.order_items = order_items;
}
}
Create another Getter setter class of variable you want to add in arraylist
OrderItem:-
public class OrderItem {
String product_name;
int product_total;
public OrderItem(String product_name, int product_total) {
this.product_name = product_name;
this.product_total = product_total;
}
public String getProduct_name() {
return product_name;
}
public void setProduct_name(String product_name) {
this.product_name = product_name;
}
public int getProduct_total() {
return product_total;
}
public void setProduct_total(int product_total) {
this.product_total = product_total;
}
}
Now in your onClick method just create new List as below
public void onClick(View view) {
String checkbox = "";
CompleteOrder completeOrder=new CompleteOrder();
List<OrderItem> masterProductorderCount=new ArrayList<>();
for (ProductModel hold : productAdapter.getAllData()) {
int total = Integer.parseInt(hold.getProduct_price())*(hold.getCountProduct());
if (hold.isCheckbox()) {
checkbox += "\n" + hold.getProduct_name() + " " + total;
masterProductorderCount.add(new OrderItem(holder.getProduct_name(),total);
}
}
completeOrder.setOrder_items(masterProductorderCount);
if (!checkbox.isEmpty()) {
dipilih = checkbox;
} else {
dipilih = "Anda Belum Memilih Menu.";
}
formSubmit(completeOrder);//pass object of CompleteOrder
}
});
CompleteOrder object give JSON output as below
{
"CompleteOrder":[
{
"product_name":"your product name",
"product_total":1
},
{
"product_name":"your product name",
"product_total":1
},
{
"product_name":"your product name",
"product_total":1
}
]
}
make a model that contains product name , total and etc,
then put each data into an object and put each object into an array
finally use Gson to map properties to model / list of models or the other way around.
ArrayList<Model> list = new ArrayList<>();
for (ProductModel hold : productAdapter.getAllData()) {
int total = Integer.parseInt(hold.getProduct_price())*(hold.getCountProduct());
if (hold.isCheckbox()) {
Model model = new Model();
model.productName = hold.getProduct_name();
model.total = total;
list.add(model);
}
}
String jsonArray = Gson().toJson(list);
You need to create a JSONObject for each entry in the JSONArray.
As far as I can see this should take care of it:
public void onClick(View view) {
String checkbox = "";
JSONArray jsonArray = new JSONArray();
for (ProductModel hold : productAdapter.getAllData()) {
int total = Integer.parseInt(hold.getProduct_price())*(hold.getCountProduct());
if (hold.isCheckbox()) {
checkbox += "\n" + hold.getProduct_name() + " " + total;
JSONObject jsonObj = new JSONObject();
jsonObj.put("product_name", hold.getProduct_name());
jsonObj.put("product_total", total);
jsonArray.put(jsonObj);
}
}
if (!checkbox.isEmpty()) {
dipilih = checkbox;
} else {
dipilih = "Anda Belum Memilih Menu.";
}
String jsonArrayString = jsonArray.toString();
formSubmit(dipilih);
}
Depending on your data the resulting string from jsonArrayString would be:
{[
{"product_name":"product1","product_total":1},
{"product_name":"product2","product_total":2},
{"product_name":"product3","product_total":3}
]}
I really do not know what you intend on doing with the JSON data so I just created a String "jsonArrayString".. do what ever you need to with it.
I have an RecycleView. i take an ArrayList for Fetch all my Category that i inserted in mySqliteDatabase. and finally i set this ArrayList into RecycleView using its Adapter.
Problem:
(1) First Open CategoryActivity. (no categories)
(2) Add First Category, Second, Third no one is Refreshing.
(3) but after Adding First if i go back. and come again in that Activity. and if now i am insert Second categories then all [next items] are getting refresh.
My Problem is whenever i insert 1st Category. it insert successfully but it is not shown in my RecycleView or an ArrayList [means Recycleview not refreshing].
but my Main Problem is my RecycleView is not Refreshing only FirstCategory on My ArrayList.. After adding First item my next all Arraylist item is getting Refreshed.
Below is my All Code.
CategoryAdapter
public class CategoryAdapter extends RecyclerView.Adapter<CategoryAdapter.MyViewHolder> implements Filterable {
private ArrayList<CategoryModel> dataList;
class MyViewHolder extends RecyclerView.ViewHolder {
TextView tvCategoryItem;
MyViewHolder(View view) {
super(view);
tvCategoryItem = (TextView) view.findViewById(R.id.tvCategoryName);
}
}
CategoryAdapter(ArrayList<CategoryModel> dataSet) {
this.dataList = dataSet;
this.filterList = dataSet;
}
// I used this method too. but same problem.
void refreshAdapter(ArrayList<CategoryModel> dataSet) {
dataList.clear();
dataList.addAll(dataSet);
notifyDataSetChanged();
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.rv_row_category_list, parent, false);
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
CategoryModel categoryModel = dataList.get(position);
holder.tvCategoryItem.setText(categoryModel.getCategoryName());
}
#Override
public int getItemCount() {
return dataList.size();
}
}
CategoryListActivity
MyDatabase myDb;
CategoryModel categoryModel;
RecyclerView recyclerCategory;
RecyclerView.LayoutManager layoutManager;
CategoryAdapter adapter;
ArrayList<CategoryModel> allCategory;
int CategoryType;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list_category);
myDb = new MyDatabase(this);
recyclerCategory = (RecyclerView) findViewById(R.id.recyclerCategory);
CategoryType = CaseActivity.CategoryType;
Log.d(GlobalConstant.KEY_CATEGORY_TYPE, "" + CategoryType);
allCategory = myDb.getCategoryByType(CategoryType);
if (allCategory.size() == 0) {
Toast.makeText(this, "No Category", Toast.LENGTH_SHORT).show();
}
adapter = new CategoryAdapter(allCategory);
recyclerCategory.setAdapter(adapter);
layoutManager = new LinearLayoutManager(this);
recyclerCategory.setLayoutManager(layoutManager);
recyclerCategory.setItemAnimator(new DefaultItemAnimator());
recyclerCategory.setHasFixedSize(true);
recyclerCategory.addOnItemTouchListener(new RecyclerItemClickListener(this, recyclerCategory,
new RecyclerItemClickListener.OnItemTouchListener() {
#Override
public void onItemClick(View view, int position) {
TextView tvCategoryItem = (TextView) view.findViewById(R.id.tvCategoryName);
String CategoryName = tvCategoryItem.getText().toString();
Intent intent = new Intent();
CategoryId = allCategory.get(+position).getCategoryId();
intent.putExtra("CategoryId", String.valueOf(CategoryId));
Log.e("Clicked Cat Id is ", "" + CategoryId);
intent.putExtra("CategoryName", CategoryName);
setResult(Activity.RESULT_OK, intent);
finish();
}
#Override
public void onLongItemClick(View view, int position) {
}
}
));
}
private void openAlert() {
final EditText etCategoryName = new EditText(this);
CustomAlertDialog dialog1 = new CustomAlertDialog(this);
dialog1.setTitle("Add Category");
dialog1.setView(etCategoryName);
dialog1.setCancelable(true);
dialog1.setPositiveButton("Add", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
final String CategoryName = etCategoryName.getText().toString().trim();
final String storedCategoryName = myDb.ExistCategory(CategoryName);
if (CategoryName.equals("") && CategoryName.length() == 0) {
Builder builder1 = GlobalConstant.createAlert(CategoryListActivity.this, "Warning", "Enter Category Name");
builder1.setPositiveButton("Back", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.dismiss();
}
});
} else {
if (CategoryName.equals(storedCategoryName)) {
Builder builder1 = GlobalConstant.createAlert(CategoryListActivity.this, "Warning", "Category Already Exists");
builder1.setPositiveButton("Back", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.dismiss();
}
});
} else {
dialogInterface.dismiss();
categoryModel = new CategoryModel(CategoryName, String.valueOf(CategoryType));
myDb.createCategory(categoryModel);
Toast.makeText(CategoryListActivity.this, "CategoryName " + CategoryName
+ "\nCategoryType " + CategoryType, Toast.LENGTH_SHORT).show();
allCategory.clear();
allCategory = myDb.getCategoryByType(CategoryType);
adapter.notifyDataSetChanged();
}
}
}
});
dialog1.show();
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_add:
openAlert();
default:
return super.onOptionsItemSelected(item);
}
}
}
my createCategory() method.
public long createCategory(CategoryModel categoryModel) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(CATEGORY_NAME, categoryModel.getCategoryName());
values.put(CATEGORY_TYPE, categoryModel.getCategoryType());
long CategoryId = db.insert(TABLE_CATEGORY, null, values);
db.close();
return CategoryId;
}
and Finally my getCategoryByType() method on My Database.
public ArrayList<CategoryModel> getCategoryByType(int CategoryType) {
ArrayList<CategoryModel> Categories = new ArrayList<>();
// String selectQuery = "SELECT " + CATEGORY_NAME + " FROM " + TABLE_CATEGORY + " WHERE " + CATEGORY_TYPE + " = " + CategoryType;
String selectQuery = "SELECT * FROM " + TABLE_CATEGORY + " WHERE " + CATEGORY_TYPE + " = " + CategoryType + " ORDER BY CategoryId DESC";
Log.e(DB_LOG, selectQuery);
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
if (cursor != null && cursor.getCount() > 0) {
if (cursor.moveToFirst()) {
do {
CategoryModel categoryModel = new CategoryModel();
categoryModel.setCategoryId(cursor.getInt(cursor.getColumnIndex(CATEGORY_ID)));
categoryModel.setCategoryName(cursor.getString(cursor.getColumnIndex(CATEGORY_NAME)));
categoryModel.setCategoryType(cursor.getString(cursor.getColumnIndex(CATEGORY_TYPE)));
Categories.add(categoryModel);
} while (cursor.moveToNext());
}
cursor.close();
}
return Categories;
}
Any Type of Help, Suggestion is much Appreciated.....Thanks in advance
Below is Screenshot after adding First Item.
First Item Inserted but not shown in RecycleView
My LogCat Screenshot is below.
Logcat Screenshot
change your onCreate in this way
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list_category);
myDb = new MyDatabase(this);
recyclerCategory = (RecyclerView) findViewById(R.id.recyclerCategory);
CategoryType = CaseActivity.CategoryType;
Log.d(GlobalConstant.KEY_CATEGORY_TYPE, "" + CategoryType);
allCategory = myDb.getCategoryByType(CategoryType);
if (allCategory.size() == 0) {
Toast.makeText(this, "No Category", Toast.LENGTH_SHORT).show();
}
adapter = new CategoryAdapter(allCategory);
recyclerCategory.setAdapter(adapter);
layoutManager = new LinearLayoutManager(this);
recyclerCategory.setLayoutManager(layoutManager);
recyclerCategory.setItemAnimator(new DefaultItemAnimator());
recyclerCategory.setHasFixedSize(true);
}
and now you can use adapter.notifyDataSetChanged(); without recreation of adapter and set them to RecyclerView
if you make in setPositiveButton allCategory = myDb.getCategoryByType(CategoryType); then your reference to allCategory is lost.
you need instead
allCategory.clear();
allCategory.addAll(myDb.getCategoryByType(CategoryType));
Change your Activity onCreate:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_list_category);
myDb = new MyDatabase(this);
recyclerCategory = (RecyclerView) findViewById(R.id.recyclerCategory);
CategoryType = CaseActivity.CategoryType;
Log.d(GlobalConstant.KEY_CATEGORY_TYPE, "" + CategoryType);
allCategory = new ArrayList<>();
adapter = new CategoryAdapter(allCategory);
layoutManager = new LinearLayoutManager(this);
recyclerCategory.setLayoutManager(layoutManager);
recyclerCategory.setItemAnimator(new DefaultItemAnimator());
recyclerCategory.setHasFixedSize(true);
recyclerCategory.setAdapter(adapter);
allCategory = myDb.getCategoryByType(CategoryType);
adapter.notifyDataSetChange();
if (allCategory.size() == 0) {
Toast.makeText(this, "No Category", Toast.LENGTH_SHORT).show();
}
}
and inside setPositiveButton, replace
adapter = new CategoryAdapter(allCategory);
recyclerCategory.setAdapter(adapter);
adapter.notifyDataSetChanged();
with
adapter.notifyDataSetChanged();
Also replace
allCategory = myDb.getCategoryByType(CategoryType);
with
allCategory.addAll(myDb.getCategoryByType(CategoryType));
And try to run your program again.