1
I have a project that I am developing in Android Studio where I use a Custom Adapter, an Employee and a Databasehelper.
What happens, I use a database already populated that is in the Assets folder, and this is copied to the Databases directory of the application on its initialization.
I also have a layout where it has a field for research. When searching the user click on a button and the Custom Adapter goes into action to popular Listview.
In Listview there is an Imagebuttom where I am trying to implement a routine where the user click on it so that the item in the list can be recorded as favorite. How was I doing that? Taking the sub-category number sub and the value of the favorite fav and moving on to function public void update(String sub, String fav) on the Databasehelper.
I was unable to implement the click of Imagebuttom, the only place where I could do this was in custom Adapter.
Only now I can not make the data in the table can receive the update, because by clicking on Imagebuttom the application stops working.
Databasehelper.java
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
public class DatabaseHelper extends SQLiteOpenHelper {
private final static String TAG = "Database";
private final Context myContext;
private static final String DATABASE_NAME = "my_db.db";
public static final String SUBCATEGORIA = "sub_categ";
public static final String FAV = "fav";
private static final int DATABASE_VERSION = 2;
private String pathToSaveDBFile;
public DatabaseHelper(Context context, String filePath) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
this.myContext = context;
pathToSaveDBFile = new StringBuffer(filePath).append("/").append(DATABASE_NAME).toString();
}
public void prepareDatabase() throws IOException {
boolean dbExist = checkDataBase();
if(dbExist) {
int currentDBVersion = getVersionId();
if (DATABASE_VERSION > currentDBVersion) {
deleteDb();
try {
copyDataBase();
} catch (IOException e) {
Log.e(TAG, e.getMessage());
}
}
} else {
try {
copyDataBase();
} catch (IOException e) {
Log.e(TAG, e.getMessage());
}
}
}
private boolean checkDataBase() {
boolean checkDB = false;
try {
File file = new File(pathToSaveDBFile);
checkDB = file.exists();
} catch(SQLiteException e) {
Log.d(TAG, e.getMessage());
}
return checkDB;
}
private void copyDataBase() throws IOException {
OutputStream os = new FileOutputStream(pathToSaveDBFile);
InputStream is = myContext.getAssets().open(DATABASE_NAME);
byte[] buffer = new byte[1024];
int length;
while ((length = is.read(buffer)) > 0) {
os.write(buffer, 0, length);
}
is.close();
os.flush();
os.close();
}
public void deleteDb() {
File file = new File(pathToSaveDBFile);
if(file.exists()) {
file.delete();
}
}
@Override
public void onCreate(SQLiteDatabase db) {
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
public List<Employee> getEmployees(String codigo) {
SQLiteDatabase db = SQLiteDatabase.openDatabase(pathToSaveDBFile, null, SQLiteDatabase.OPEN_READONLY);
String query = "SELECT sub_categ, descricao, descrabrev, fav FROM tab_mytabe WHERE TRIM(sub_categ) LIKE '%"+codigo+"%' OR TRIM(descricao) LIKE '%"+codigo+"%'";
Cursor cursor = db.rawQuery(query, null);
List<Employee> list = new ArrayList<>();
while(cursor.moveToNext()) {
Employee employee = new Employee();
employee.setSubcategoria(cursor.getString(0));
employee.setDescricao(cursor.getString(1));
employee.setDescrabrev(cursor.getString(2));
employee.setFavorito(cursor.getString(3));
list.add(employee);
}
db.close();
return list;
}
private int getVersionId() {
SQLiteDatabase db = SQLiteDatabase.openDatabase(pathToSaveDBFile, null, SQLiteDatabase.OPEN_READONLY);
String query = "SELECT versao FROM tab_versao";
Cursor cursor = db.rawQuery(query, null);
cursor.moveToFirst();
int v = cursor.getInt(0);
db.close();
return v;
}
}
Customadapter.java
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ArrayAdapter;
import android.widget.ImageButton;
import android.widget.TextView;
import java.util.ArrayList;
public class CustomAdapter extends ArrayAdapter<Employee> implements View.OnClickListener{
Animation animText;
String sub;
String fav;
private ArrayList<Employee> dataSet;
Context mContext;
// View lookup cache
private static class ViewHolder {
TextView subcategoria;
TextView descricao;
TextView descrabrev;
ImageButton favorito;
}
public CustomAdapter(ArrayList<Employee> data, Context context) {
super(context, R.layout.lista, data);
this.dataSet = data;
this.mContext=context;
}
@Override
public void onClick(View v) {
int position=(Integer) v.getTag();
Object object= getItem(position);
Employee dataModel=(Employee) object;
}
private int lastPosition = -1;
@Override
public View getView(int position, View convertView, final ViewGroup parent) {
animText = AnimationUtils.loadAnimation(mContext, R.anim.anima_text);
final Employee dataModel = getItem(position);
final ViewHolder viewHolder; // view lookup cache stored in tag
final View result;
if (convertView == null) {
viewHolder = new ViewHolder();
LayoutInflater inflater = LayoutInflater.from(getContext());
convertView = inflater.inflate(R.layout.lista, parent, false);
viewHolder.subcategoria = (TextView) convertView.findViewById(R.id.tv_subcategoria);
viewHolder.descrabrev = (TextView) convertView.findViewById(R.id.tv_descriabreviada);
viewHolder.descricao = (TextView) convertView.findViewById(R.id.tv_descricao);
viewHolder.favorito = (ImageButton)convertView.findViewById(R.id.btnFav);
result=convertView;
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
result=convertView;
}
viewHolder.subcategoria.setText(dataModel.getSubcategoria());
viewHolder.descrabrev.setText(dataModel.getDescrabrev());
viewHolder.descricao.setText(dataModel.getDescricao());
if (dataModel.getFavorito().equals("1")){
viewHolder.favorito.setBackgroundResource(R.drawable.ic_fav_seleted);
}else if (dataModel.getFavorito().equals("0")){
viewHolder.favorito.setBackgroundResource(R.drawable.ic_fav);
}
viewHolder.favorito.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
sub = dataModel.getSubcategoria();
if (dataModel.getFavorito().equals("1")){
fav = "0";
}else if (dataModel.getFavorito().equals("0")){
fav = "1";
}
viewHolder.favorito.startAnimation(animText);
}
});
return convertView;
}
}
How could I fix this?
Note. The update routine was just below the getVersionId() function of the Databasehelper, I withdrew because it was not working. The call for the update function was in viewHolder.favorito.setOnClickListener of the above code.
NX thanks for the reply!
I made the changes in Custom Adapter inserting the codes. This is how:
...
//Ação ao clicar no ImageButtom
viewHolder.favorito.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
sub = dataModel.getSubcategoria();
if (mOnFavoriteEmployeeListener != null) {
boolean fav = dataModel.getFavorito().equals("1");
mOnFavoriteEmployeeListener.onFavorite(dataModel, fav);
}
viewHolder.favorito.startAnimation(animText);
}
});
return convertView;
}
//Interface criada para a ação de update do favorito
interface OnFavoriteEmployeeListener {
void onFavorite(Employee e, boolean fav);
}
private OnFavoriteEmployeeListener mOnFavoriteEmployeeListener;
public void setOnFavoriteEmployeeListener(OnFavoriteEmployeeListener l) {
mOnFavoriteEmployeeListener = l;
}
But in the Activity I couldn’t see where I put the code, because I tried to put it but it’s killing the application.
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.AlertDialog;
import android.support.design.widget.NavigationView;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener {
private ListView lv;
Animation animText;
ImageView search;
EditText textsearch;
TextView vazio;
String codigo;
//Custom Adapter
ArrayList<Employee> dataModels;
ListView listView;
private static CustomAdapter adapter;
//Final Custom Adapter
DatabaseHelper dbHelper= null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
animText = AnimationUtils.loadAnimation(this, R.anim.anima_text);
search = (ImageView)findViewById(R.id.img_Search);
favoritar = (ImageButton)findViewById(R.id.btnFav);
textsearch = (EditText)findViewById(R.id.edt_Search);
vazio = (TextView)findViewById(R.id.textViewV);
vazio.setVisibility(View.INVISIBLE);
lv = (ListView) findViewById(R.id.listview);
search.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
codigo = textsearch.getText().toString();
search.startAnimation(animText);
if((verificaCampos(textsearch.getText().toString()) != false)) {
dbHelper = new DatabaseHelper(MainActivity.this, getFilesDir().getAbsolutePath());
try {
dbHelper.prepareDatabase();
} catch (IOException e) {
Log.e(TAG, e.getMessage());
}
//Datamodels
List<Employee> list = dbHelper.getEmployees(codigo);
dataModels = new ArrayList<>();
for (int i =0; i< list.size(); i++) {
dataModels.add(list.get(i));
}
adapter = new CustomAdapter(dataModels, getApplicationContext());
lv.setAdapter(adapter);
if(adapter.isEmpty()){
vazio.setVisibility(View.VISIBLE);
}else{
vazio.setVisibility(View.INVISIBLE);
}
//Fim Data Models
}else{
mensagem();
}
}
});
//Final Pesquisa
}
private boolean verificaCampos(String campo1){
return campo1.trim().length() != 0;
}
}
ERROR
E/AndroidRuntime: FATAL EXCEPTION: main Process: br.com.projeto, PID: 25365 Theme: themes:{default=overlay:system, iconPack:system, fontPkg:system, com.android.systemui=overlay:system, com.android.systemui.navbar=overlay:system} java.lang.RuntimeException: Unable to start activity ComponentInfo{br.com.projeto/br.com.projeto.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void br.com.projeto.CustomAdapter.setOnFavoriteEmployeeListener(br.com.projeto.Cus tomAdapter$OnFavoriteEmployeeListener)' on a null object reference at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2450) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2510) at android.app.ActivityThread.-wrap11(ActivityThread.java) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1363) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:148) at android.app.ActivityThread.main(ActivityThread.java:5461) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:72 6) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void br.com.projeto.CustomAdapter.setOnFavoriteEmployeeListener(br.com.projeto.Cus tomAdapter$OnFavoriteEmployeeListener)' on a null object reference at br.com.projeto.MainActivity.onCreate(MainActivity.java:118) at android.app.Activity.performCreate(Activity.java:6251) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1108) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2403) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2510) at android.app.ActivityThread.-wrap11(ActivityThread.java) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1363) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:148) at android.app.ActivityThread.main(ActivityThread.java:5461) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Where am I going wrong?
After the new amendments
After the changes in the code, the logic was as follows:
Customadapter
....
//Ação ao clicar no ImageButtom
viewHolder.favorito.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
sub = dataModel.getSubcategoria();
if (mOnFavoriteEmployeeListener != null) {
boolean fav = dataModel.getFavorito().equals("1");
mOnFavoriteEmployeeListener.onFavorite(dataModel, fav);
}
viewHolder.favorito.startAnimation(animText);
}
});
return convertView;
}
private OnFavoriteEmployeeListener mOnFavoriteEmployeeListener;
//Interface criada para a ação de update do favorito
interface OnFavoriteEmployeeListener {
void onFavorite(Employee e, boolean fav);
}
public void setOnFavoriteEmployeeListener(OnFavoriteEmployeeListener l) {
mOnFavoriteEmployeeListener = l;
}
Mainactivity
...
adapter = new CustomAdapter(dataModels, getApplicationContext());
adapter.setOnFavoriteEmployeeListener(new CustomAdapter.OnFavoriteEmployeeListener() {
public void onFavorite(Employee e, boolean fav) {
dbHelper.update(e.getSubcategoria(), fav ? "1" : "0");
}
});
lv.setAdapter(adapter);
Databasehelper
//Faz o update da tabela ao clicar no ImageButtom
public void update(String sub, String fav){
SQLiteDatabase db = SQLiteDatabase.openDatabase(pathToSaveDBFile, null, SQLiteDatabase.OPEN_READWRITE);
String query = "UPDATE tab_mytabe SET fav = '"+fav+"' WHERE sub_categ = '"+sub+"'";
db.execSQL(query);
db.close();
}
However, it is not performing any action in the database and shows no apparent error.
Bank update problem solved
I figured out what was going on, the code part in Activity was that way:
...
dbHelper.update(e.getSubcategoria(), fav ? "1" : "0");
...
When Imagebuttom was clicked the update usually happened only that the value did not change because if the value of the field in the table was "0" when clicking on Imagebuttom the value would still be "0", because the value true is 1, so no change was seen. It was only changing position the numbers that worked perfectly. So with the change was as follows:
...
dbHelper.update(e.getSubcategoria(), fav ? "0" : "1");
...
The app stops working because some error happens. It has as you insert the error in your question?
– viana
The error is just below Ack
– Henqsan
Edit the
onCreate
putting where issetOnFavoriteEmployeeListener
– NX1125