Функция Create, Read, Write, Update и Delete работает, но когда я пытаюсь добавить viewview, который фильтрует recyclerView, мое приложение закрывается. Я знаю, что должно быть что-то не так, как в зависимостях, также проверил манифест, но наверняка проблема заключается в коде для выполнения поискового фильтра (здесь блок комментария - это код, который я пытался выполнить поисковым фильтром в действии VIewlist)
**The inputs are saved using sqlite, thanks guys
вот logcat
вот logcat2
line189
line202 вот код
The main activity just directs the user in/ Onclick listener to add record activity and view list activity using buttons*/
////////////////////////////////////////////PersonDbHelper/////////////////////////////////////////////////
package info.codestart.glinogaprdrecrds.Utils;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.widget.Toast;
import java.util.LinkedList;
import java.util.List;
import info.codestart.glinogaprdrecrds.model.Person;
public class PersonDBHelper extends SQLiteOpenHelper {
public static final String DATABASE_NAME = "people.db";
private static final int DATABASE_VERSION = 3 ;
public static final String TABLE_NAME = "People";
public static final String COLUMN_ID = "_id";
public static final String COLUMN_PERSON_NAME = "name";
public static final String COLUMN_PERSON_AGE = "age";
public static final String COLUMN_PERSON_DATE = "date";
public static final String COLUMN_PERSON_ADDRESS = "address";
public static final String COLUMN_PERSON_NUMBER = "number";
public static final String COLUMN_PERSON_LEFT = "lft";
public static final String COLUMN_PERSON_RIGHT = "rght";
public static final String COLUMN_PERSON_PAYMENT = "payment";
public PersonDBHelper(Context context) {
super(context, DATABASE_NAME , null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(" CREATE TABLE " + TABLE_NAME + " (" +
COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
COLUMN_PERSON_NAME + " TEXT NOT NULL, " +
COLUMN_PERSON_AGE + " NUMBER NOT NULL, " + COLUMN_PERSON_DATE + " TEXT NOT NULL, " +
COLUMN_PERSON_ADDRESS + " TEXT NOT NULL, " + COLUMN_PERSON_NUMBER + " NUMBER NOT NULL, " +
COLUMN_PERSON_LEFT + " TEXT NOT NULL, " + COLUMN_PERSON_RIGHT + " TEXT NOT NULL, " +
COLUMN_PERSON_PAYMENT + " TEXT NOT NULL);"
);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// you can implement here migration process
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
this.onCreate(db);
}
/**create record**/
public void saveNewPerson(Person person) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(COLUMN_PERSON_NAME, person.getName());
values.put(COLUMN_PERSON_AGE, person.getAge());
values.put(COLUMN_PERSON_DATE, person.getDate());
values.put(COLUMN_PERSON_ADDRESS, person.getAddress());
values.put(COLUMN_PERSON_NUMBER, person.getContactnumber());
values.put(COLUMN_PERSON_LEFT, person.getLefteyegrade());
values.put(COLUMN_PERSON_RIGHT, person.getRighteyegrade());
values.put(COLUMN_PERSON_PAYMENT, person.getPayment());
// insert
db.insert(TABLE_NAME,null, values);
db.close();
}
/**Query records, give options to filter results**/
public List<Person> peopleList(String filter) {
String query;
if(filter.equals("")){
//regular query
query = "SELECT * FROM " + TABLE_NAME;
}else{
//filter results by filter option provided
query = "SELECT * FROM " + TABLE_NAME + " ORDER BY "+ filter;
}
List<Person> personLinkedList = new LinkedList<>();
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(query, null);
Person person;
if (cursor.moveToFirst()) {
do {
person = new Person();
person.setId(cursor.getLong(cursor.getColumnIndex(COLUMN_ID)));
person.setName(cursor.getString(cursor.getColumnIndex(COLUMN_PERSON_NAME)));
person.setAge(cursor.getString(cursor.getColumnIndex(COLUMN_PERSON_AGE)));
person.setDate(cursor.getString(cursor.getColumnIndex(COLUMN_PERSON_DATE)));
personLinkedList.add(person);
} while (cursor.moveToNext());
}
return personLinkedList;
}
/**Query only 1 record**/
public Person getPerson(long id){
SQLiteDatabase db = this.getWritableDatabase();
String query = "SELECT * FROM " + TABLE_NAME + " WHERE _id="+ id;
Cursor cursor = db.rawQuery(query, null);
Person receivedPerson = new Person();
if(cursor.getCount() > 0) {
cursor.moveToFirst();
receivedPerson.setName(cursor.getString(cursor.getColumnIndex(COLUMN_PERSON_NAME)));
receivedPerson.setAge(cursor.getString(cursor.getColumnIndex(COLUMN_PERSON_AGE)));
receivedPerson.setDate(cursor.getString(cursor.getColumnIndex(COLUMN_PERSON_DATE)));
receivedPerson.setAddress(cursor.getString(cursor.getColumnIndex(COLUMN_PERSON_ADDRESS)));
receivedPerson.setContactnumber(cursor.getString(cursor.getColumnIndex(COLUMN_PERSON_NUMBER)));
receivedPerson.setLefteyegrade(cursor.getString(cursor.getColumnIndex(COLUMN_PERSON_LEFT)));
receivedPerson.setRighteyegrade(cursor.getString(cursor.getColumnIndex(COLUMN_PERSON_RIGHT)));
receivedPerson.setPayment(cursor.getString(cursor.getColumnIndex(COLUMN_PERSON_PAYMENT)));
}
return receivedPerson;
}
/**delete record**/
public void deletePersonRecord(long id, Context context) {
SQLiteDatabase db = this.getWritableDatabase();
db.execSQL("DELETE FROM "+TABLE_NAME+" WHERE _id='"+id+"'");
Toast.makeText(context, "Deleted successfully.", Toast.LENGTH_SHORT).show();
}
/**update record**/
public void updatePersonRecord(long personId, Context context, Person updatedperson) {
SQLiteDatabase db = this.getWritableDatabase();
//you can use the constants above instead of typing the column names
db.execSQL("UPDATE "+TABLE_NAME+" SET name ='"+ updatedperson.getName() + "', age ='" + updatedperson.getAge()+ "', date ='"+ updatedperson.getDate() + "', address ='"+ updatedperson.getAddress()+ "', number ='"+ updatedperson.getContactnumber()+ "', lft ='"+ updatedperson.getLefteyegrade()+ "', rght ='"+ updatedperson.getRighteyegrade()+ "', payment ='"+ updatedperson.getPayment()+ "' WHERE _id='" + personId + "'");
Toast.makeText(context, "Updated successfully.", Toast.LENGTH_SHORT).show();
}
}
////////////////////////////////////////////////Person Adapter////////////////////////////////////////////////
package info.glinogaprdrecrds.recrdapp.Utils;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
import info.codestart.glinogaprdrecrds.R;
import info.codestart.glinogaprdrecrds.UpdateRecordActivity;
import info.codestart.glinogaprdrecrds.Utils.PersonDBHelper;
import info.codestart.glinogaprdrecrds.model.Person;
public class PersonAdapter extends RecyclerView.Adapter<PersonAdapter.ViewHolder> implements Filterable {
private List<Person> mPeopleList;
private List<Person> exampleListFull;
private Context mContext;
private RecyclerView mRecyclerV;
// Provide a reference to the views for each data item
// Complex data items may need more than one view per item, and
// you provide access to all the views for a data item in a view holder
public class ViewHolder extends RecyclerView.ViewHolder {
// each data item is just a string in this case
public TextView personNameTxtV;
public TextView personAgeTxtV;
public TextView personDateTxtV;
public View layout;
public ViewHolder(View v) {
super(v);
layout = v;
personNameTxtV = (TextView) v.findViewById(R.id.name);
personAgeTxtV = (TextView) v.findViewById(R.id.age);
personDateTxtV = (TextView) v.findViewById(R.id.date);
}
}
public PersonAdapter(List<Person> mPeopleList){
this.mPeopleList = mPeopleList;
exampleListFull = new ArrayList<>(mPeopleList);
}
public void add(int position, Person person) {
mPeopleList.add(position, person);
notifyItemInserted(position);
}
public void remove(int position) {
mPeopleList.remove(position);
notifyItemRemoved(position);
}
// Provide a suitable constructor (depends on the kind of dataset)
public PersonAdapter(List<Person> myDataset, Context context, RecyclerView recyclerView) {
mPeopleList = myDataset;
mContext = context;
mRecyclerV = recyclerView;
}
// Create new views (invoked by the layout manager)
@Override
public PersonAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
// create a new view
LayoutInflater inflater = LayoutInflater.from(
parent.getContext());
View v =
inflater.inflate(R.layout.single_row, parent, false);
// set the view's size, margins, paddings and layout parameters
ViewHolder vh = new ViewHolder(v);
return vh;
}
// Replace the contents of a view (invoked by the layout manager)
@Override
public void onBindViewHolder(ViewHolder holder, final int position) {
// - get element from your dataset at this position
// - replace the contents of the view with that element
final Person person = mPeopleList.get(position);
holder.personNameTxtV.setText("Name: " + person.getName());
holder.personAgeTxtV.setText("Age: " + person.getAge());
holder.personDateTxtV.setText("Date: " + person.getDate());
//listen to single view layout click
holder.layout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
builder.setTitle("Choose option");
builder.setMessage("Update or delete user?");
builder.setPositiveButton("Update", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//go to update activity
goToUpdateActivity(person.getId());
}
});
builder.setNeutralButton("Delete", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
PersonDBHelper dbHelper = new PersonDBHelper(mContext);
dbHelper.deletePersonRecord(person.getId(), mContext);
mPeopleList.remove(position);
mRecyclerV.removeViewAt(position);
notifyItemRemoved(position);
notifyItemRangeChanged(position, mPeopleList.size());
notifyDataSetChanged();
}
});
builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
builder.create().show();
}
});
}
private void goToUpdateActivity(long personId){
Intent goToUpdate = new Intent(mContext, UpdateRecordActivity.class);
goToUpdate.putExtra("USER_ID", personId);
mContext.startActivity(goToUpdate);
}
// Return the size of your dataset (invoked by the layout manager)
@Override
public int getItemCount() {
return mPeopleList.size();
}
@Override
public Filter getFilter(){
return exampleFilter;
}
private Filter exampleFilter = new Filter() {
@Override
protected FilterResults performFiltering(CharSequence charSequence) {
List<Person> filteredList = new ArrayList<>();
if(charSequence == null || charSequence.length()==0){
filteredList.addAll(exampleListFull);
}else{
String filterPatern = charSequence.toString().toLowerCase().trim();
for (Person item : exampleListFull){
if(item.getName().toLowerCase().contains(filterPatern)){
filteredList.add(item);
}
}
}
FilterResults results = new FilterResults();
results.values = filteredList;
return results;
}
@Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
mPeopleList.clear();
mPeopleList.addAll((List)filterResults.values);
notifyDataSetChanged();
}
};
}
//////////////////////////////////////////////ViewList////////////////////////////////////////////////
package info.codestart.glinogaprdrecrds;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.widget.SearchView;
import java.util.List;
import info.codestart.glinogaprdrecrds.Utils.PersonDBHelper;
import info.codestart.glinogaprdrecrds.model.Person;
import info.glinogaprdrecrds.recrdapp.Utils.PersonAdapter;
public class viewList extends AppCompatActivity {
private RecyclerView mRecyclerView;
private RecyclerView.LayoutManager mLayoutManager;
private PersonDBHelper dbHelper;
private PersonAdapter adapter;
private String filter = "";
private List<Person> exampleList;
private SearchView searchView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_view_list);
//initialize the variables
mRecyclerView = (RecyclerView)findViewById(R.id.recyclerView);
mRecyclerView.setHasFixedSize(true);
// use a linear layout manager
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);
populaterecyclerView(filter);
}
private void populaterecyclerView(String filter){
dbHelper = new PersonDBHelper(this);
adapter = new PersonAdapter(dbHelper.peopleList(filter), this, mRecyclerView);
mRecyclerView.setAdapter(adapter);
}
@Override
protected void onResume() {
super.onResume();
adapter.notifyDataSetChanged();
}
/*
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.example_menu, menu);
MenuItem searchItem = menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) searchItem.getActionView();
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
adapter.getFilter().filter(newText);
return false;
}
});
return true;
}
*/
}
///////////////////////////////////////////////UpdateRecordActivity//////////////////////////////////////
package info.codestart.glinogaprdrecrds;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import info.codestart.glinogaprdrecrds.Utils.PersonDBHelper;
import info.codestart.glinogaprdrecrds.model.Person;
public class UpdateRecordActivity extends AppCompatActivity {
private EditText mNameEditText;
private EditText mAgeEditText;
private EditText mAddressEditText;
private EditText mDateEditText;
private EditText mContactNumberText;
private EditText mLeftEyeGradeEditText;
private EditText mRightEyeGradeEditText;
private EditText mPaymentEditText;
private Button UpdateUser;
private PersonDBHelper dbHelper;
private long receivedPersonId;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_update_record);
mNameEditText = findViewById(R.id.userNameUpdate);
mAgeEditText = findViewById(R.id.userAgeUpdate);
mAddressEditText = findViewById(R.id.userAddressUpdate);
mDateEditText = findViewById(R.id.userDateUpdate);
mContactNumberText = findViewById(R.id.userContactNumberUpdate);
mLeftEyeGradeEditText = findViewById(R.id.userLeftEyeGradeUpdate);
mRightEyeGradeEditText = findViewById(R.id.userRightEyeGradeUpdate);
mPaymentEditText = findViewById(R.id.userPaymentUpdate);
UpdateUser = findViewById(R.id.UpdateUser);
dbHelper = new PersonDBHelper(this);
try {
//get intent to get person id
receivedPersonId = getIntent().getLongExtra("USER_ID", 1);
} catch (Exception e) {
e.printStackTrace();
}
/***populate user data before update***/
Person queriedPerson = dbHelper.getPerson(receivedPersonId);
//set field to this user data
mNameEditText.setText(queriedPerson.getName());
mAgeEditText.setText(queriedPerson.getAge());
mAddressEditText.setText(queriedPerson.getAddress());
mDateEditText.setText(queriedPerson.getDate());
mContactNumberText.setText(queriedPerson.getContactnumber());
mLeftEyeGradeEditText.setText(queriedPerson.getLefteyegrade());
mRightEyeGradeEditText.setText(queriedPerson.getRighteyegrade());
mPaymentEditText.setText(queriedPerson.getPayment());
//listen to add button click to update
UpdateUser.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//call the save person method
updateUser();
}
});
}
private void updateUser(){
String name = mNameEditText.getText().toString().trim();
String age = mAgeEditText.getText().toString().trim();
String address = mAddressEditText.getText().toString().trim();
String date = mDateEditText.getText().toString().trim();
String contactnumber = mContactNumberText.getText().toString().trim();
String lefteyegrade = mLeftEyeGradeEditText.getText().toString().trim();
String righteyegrade = mRightEyeGradeEditText.getText().toString().trim();
String payment = mPaymentEditText.getText().toString().trim();
if(name.isEmpty() && age.isEmpty()&& address.isEmpty()&& date.isEmpty()&& contactnumber.isEmpty()&& lefteyegrade.isEmpty()&& righteyegrade.isEmpty()&& payment.isEmpty() ){
Toast.makeText(this,"You must fill up all fields", Toast.LENGTH_SHORT).show();
}
Person updatedPersonRecord = new Person(name, age, address, date, contactnumber, lefteyegrade, righteyegrade, payment);
dbHelper.updatePersonRecord(receivedPersonId, this, updatedPersonRecord);
gotolist();
}
private void gotolist(){
startActivity(new Intent(this, info.codestart.glinogaprdrecrds.MainActivity.class));
}
}
//I modified this code to add more user inputs and some layout from the original template that I followed in youtube tutorials