Related
I wanna create a recyclerview which can retrieve data from database, and followed this video step by step. The application "has stopped" when I tried to run it.I I have no idea where I got it wrong. Please help.
activity_main.xml
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=".MainActivity"
android:padding="16dp">
<EditText
android:id="#+id/edittext_name"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/textviewamount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/edittext_name"
android:layout_centerHorizontal="true"
android:text="0"
android:textSize="50sp"
android:layout_marginTop="8dp"
/>
<Button
android:id="#+id/button_decrease"
android:layout_width="50dp"
android:layout_height="72dp"
android:layout_alignTop="#+id/textviewamount"
android:layout_toStartOf="#+id/textviewamount"
android:layout_toLeftOf="#+id/textviewamount"
android:text="-" />
<Button
android:id="#+id/button_increase"
android:layout_width="50dp"
android:layout_height="72dp"
android:layout_alignTop="#+id/textviewamount"
android:layout_toEndOf="#+id/textviewamount"
android:layout_toRightOf="#+id/textviewamount"
android:text="+" />
<Button
android:id="#+id/button_add"
android:layout_width="wrap_content"
android:layout_height="72dp"
android:layout_alignEnd="#+id/edittext_name"
android:layout_alignRight="#+id/edittext_name"
android:layout_alignTop="#+id/textviewamount" />
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/button_decrease"
android:layout_centerHorizontal="true">
</android.support.v7.widget.RecyclerView>
grocery_item.xml
android:layout_margin="8dp"
>
<TextView
android:id="#+id/textview_amount_item"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0"
android:textSize="30sp"
/>
<TextView
android:id="#+id/textview_name_item"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Empty Item"
android:textSize="30sp"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
/>
MainActivity.java
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private SQLiteDatabase mDatabase;
private GroceryAdapter mAdapter;
private EditText mEditTextName;
private TextView mTextViewAmount;
private int mAmount = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
GroceryDBHelper dbHelper = new GroceryDBHelper(this);
mDatabase = dbHelper.getWritableDatabase();
//能往database里写数据的必须语句
RecyclerView recyclerView = findViewById(R.id.recyclerview);
//MainActivit.xml里的recyclerView
recyclerView.setLayoutManager(new LinearLayoutManager(this));
mAdapter = new GroceryAdapter(this,getAllItems());
//cursor的位置放getAllItems方法来传指针
recyclerView.setAdapter(mAdapter);
mEditTextName = findViewById(R.id.edittext_name);
mTextViewAmount = findViewById(R.id.textview_amount_item);
Button buttonIncrease = findViewById(R.id.button_increase);
Button buttonDecrease = findViewById(R.id.button_decrease);
Button buttonAdd = findViewById(R.id.button_add);
buttonIncrease.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
increase();
}
});
buttonDecrease.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
decrease();
}
});
buttonAdd.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
addItem();
}
});
}
private void increase()
{
mAmount++;
mTextViewAmount.setText(String.valueOf(mAmount));
}
private void decrease() {
if (mAmount > 0) {
mAmount--;
mTextViewAmount.setText(String.valueOf(mAmount));
}
}
private void addItem()
//往database里加item的方法
{
if (mEditTextName.getText().toString().trim().length() == 0 || mAmount == 0)
//trim:删除句首和句尾的空格
{
return;
//如果每输入或输入数量为0,就不添加item,直接返回additem方法
}
String name = mEditTextName.getText().toString();
ContentValues cv = new ContentValues();
cv.put(GroceryContract.GroceryEntry.COLUMN_NAME, name);
//将name放入database的name column里
cv.put(GroceryContract.GroceryEntry.COLUMN_AMOUNT, mAmount);
//将数量放入database的amount column里
//无需手动添加id和stamp,会自动添加
mDatabase.insert(GroceryContract.GroceryEntry.TABLE_NAME,null, cv);
//将cv放入database的table里
mAdapter.swapCursor(getAllItems());
//添加新item后转换指针
mEditTextName.getText().clear();
//清空输入栏
}
private Cursor getAllItems()
{
return mDatabase.query(
GroceryContract.GroceryEntry.TABLE_NAME,
null,
null,
null,
null,
null,
GroceryContract.GroceryEntry.COLUMN_TIMESTAMP + " DESC"
//decending order
);
}
}
GroceryDBHelper.java
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import com.playah.recyclerdatabase.GroceryContract.*;
public class GroceryDBHelper extends SQLiteOpenHelper {
public static final String DATABASE_NAME = "grocerylist.db";
public static final int DATABASE_VERSION = 1;
//这个数字是database的scheme
public GroceryDBHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
final String SQL_CREATE_GROCERYLIST_TABLE = "CREATE TABLE "+
GroceryEntry.TABLE_NAME + " (" +
GroceryEntry._ID + "INTEGER PRIMARY KEY AUTOINCREMENT, "+
//ID没创建,但是已经GroceryContract.java里通过BaseColumn引入
//primary key:unique identify of the row
//autoincrement: 每往table加一行就添加一次
GroceryEntry.COLUMN_NAME + "TEXT NOT NULL," +
//not null: we have to provide a value
GroceryEntry.COLUMN_AMOUNT + "INTEGER NOT NULL," +
GroceryEntry.COLUMN_TIMESTAMP +"TIMESTAMP DEFAULT CURRENT_TIMESTAMP" +
//每往table加一行就在当前位置创建一次time stamp
");";
db.execSQL(SQL_CREATE_GROCERYLIST_TABLE);
//执行创建database
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + GroceryEntry.TABLE_NAME);
//如果database已存在,drop并重建
onCreate(db);
}
}
**GroceryContract**
import android.provider.BaseColumns;
public class GroceryContract
{ private GroceryContract() {}
//引入interface
public static final class GroceryEntry implements BaseColumns {
//展示table的id columns
public static final String TABLE_NAME = "groceryList";
//table name
public static final String COLUMN_NAME = "name";
//first column of the table
public static final String COLUMN_AMOUNT = "amount";
//amount of the item
public static final String COLUMN_TIMESTAMP = "timestemp";
}
}
GroceryContract.java
import android.provider.BaseColumns;
public class GroceryContract
//为table定义字符实体和行数
{ private GroceryContract() {}
//用的是下面的方法,用不到这个方法来构造函数
//引入interface
public static final class GroceryEntry implements BaseColumns {
//展示table的id columns
public static final String TABLE_NAME = "groceryList";
//table name
public static final String COLUMN_NAME = "name";
//first column of the table
public static final String COLUMN_AMOUNT = "amount";
//amount of the item
public static final String COLUMN_TIMESTAMP = "timestemp";
//改变item的数量
}
}
GroceryAdapter.java
import android.content.Context;
import android.database.Cursor;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class GroceryAdapter extends RecyclerView.Adapter<GroceryAdapter.GroceryViewHolder> {
private Context mContext;
private Cursor mCursor;
public GroceryAdapter(Context context, Cursor cursor)
//cursor使能够从database取出数据
{
mContext = context;
mCursor = cursor;
}
public class GroceryViewHolder extends RecyclerView.ViewHolder
{
public TextView nameText;
public TextView countText;
public GroceryViewHolder(#NonNull View itemView) {
super(itemView);
nameText = itemView.findViewById(R.id.textview_name_item);
countText = itemView.findViewById(R.id.textview_amount_item);
}
}
#NonNull
#Override
public GroceryViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(mContext);
View view = inflater.inflate(R.layout.grocery_item, parent, false);
//使用recyclervew的layout
return new GroceryViewHolder(view);
}
#Override
public void onBindViewHolder(#NonNull GroceryViewHolder holder, int position) {
if (!mCursor.moveToPosition(position)){
//判断cursor是否存在
return;
}
String name = mCursor.getString(mCursor.getColumnIndex(GroceryContract.GroceryEntry.COLUMN_NAME));
int amount = mCursor.getInt(mCursor.getColumnIndex(GroceryContract.GroceryEntry.COLUMN_AMOUNT));
//从database中取得上面两种数据
holder.nameText.setText(name);
holder.countText.setText(String.valueOf(amount));
}
#Override
public int getItemCount() {
return mCursor.getCount();
}
public void swapCursor(Cursor newCursor)
//转换cursor,为了使数据库更新后cursor在正确的位置
{
if (mCursor !=null){
mCursor.close();
}
mCursor = newCursor;
if(newCursor != null){
notifyDataSetChanged();
}
}
Here is the logcat
--------- beginning of crash
08-13 15:51:49.125 5572-5572/com.playah.recyclerdatabase E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.playah.recyclerdatabase, PID: 5572
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.playah.recyclerdatabase/com.playah.recyclerdatabase.MainActivity}: android.database.sqlite.SQLiteException: AUTOINCREMENT is only allowed on an INTEGER PRIMARY KEY (code 1): , while compiling: CREATE TABLE groceryList (_idINTEGER PRIMARY KEY AUTOINCREMENT, nameTEXT NOT NULL,amountINTEGER NOT NULL,timestempTIMESTAMP DEFAULT CURRENT_TIMESTAMP);
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2817)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
Caused by: android.database.sqlite.SQLiteException: AUTOINCREMENT is only allowed on an INTEGER PRIMARY KEY (code 1): , while compiling: CREATE TABLE groceryList (_idINTEGER PRIMARY KEY AUTOINCREMENT, nameTEXT NOT NULL,amountINTEGER NOT NULL,timestempTIMESTAMP DEFAULT CURRENT_TIMESTAMP);
at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:889)
at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:500)
at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:588)
at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
at android.database.sqlite.SQLiteStatement.<init>(SQLiteStatement.java:31)
at android.database.sqlite.SQLiteDatabase.executeSql(SQLiteDatabase.java:1677)
at android.database.sqlite.SQLiteDatabase.execSQL(SQLiteDatabase.java:1608)
at com.playah.recyclerdatabase.GroceryDBHelper.onCreate(GroceryDBHelper.java:33)
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:294)
at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:194)
at com.playah.recyclerdatabase.MainActivity.onCreate(MainActivity.java:35)
at android.app.Activity.performCreate(Activity.java:6975)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1213)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2770)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
Add space before INTEGER in double qots
GroceryEntry._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
It looks like your CREATE clause misses spaces between the column names and their types.
Try to add a blank space after the column ids, like this :
GroceryEntry._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
Right before the keyword "INTEGER". Do the same for the other lines.
I am populating a ListView of songs using Firebase database and Firebase-UI, all the dependencies are initialized correctly and the app is connected with the database but when it displays the list it doesn't display the text, just empty boxes like that:
When an item is added to the database then a box is added but it doesn't show the text. Here is the code:
Song class:
package com.example.gloriadesideri.animas;
public class Song
{
private String myName;
private String myURL;
private String myAuthor;
public Song(){
/*myName="";
myURL="";
myAuthor="";*/
}
public Song(String Author, String Song, String URL) {
this.myName=Song;
this.myURL=URL;
this.myAuthor=Author;
}
public String getName()
{
return myName;
}
public String getURL()
{
return myURL;
}
public String getAuthor()
{
return myAuthor;
}
public void setName(String name)
{
this.myName=name;
}
public void setURL ( String URL)
{
this.myURL=URL;
}
public void setAuthor(String author)
{
this.myAuthor=author;
}
}
Song 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="vertical"
android:layout_margin="20dp"
android:padding="10dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/songName"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/author"/>
</LinearLayout>
Activity that should have the list view:
package com.example.gloriadesideri.animas;
import android.content.Intent;
import android.support.design.widget.NavigationView;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.MenuItem;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import com.firebase.ui.database.FirebaseListAdapter;
import com.firebase.ui.database.FirebaseListOptions;
import com.google.firebase.database.ChildEventListener;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.Query;
import com.google.firebase.database.ValueEventListener;
import java.util.ArrayList;
import java.util.List;
public class Canzoni extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener
{
//nav view parameters
private DrawerLayout cDrawerLayout;
private ActionBarDrawerToggle cToggle;
//list view parameters
private ListView mListView;
//firebase parameters
private FirebaseListAdapter mAdapter;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_canzoni);
//nav view code
cDrawerLayout= (DrawerLayout) findViewById(R.id.draw_viewC);
cToggle= new ActionBarDrawerToggle(this, cDrawerLayout,R.string.Open, R.string.Close);
cDrawerLayout.addDrawerListener(cToggle);
cToggle.syncState();
ActionBar actionBar = getSupportActionBar();
if (actionBar != null)
actionBar.setDisplayHomeAsUpEnabled(true);
NavigationView cNavigationView = (NavigationView) findViewById(R.id.nav_viewC);
if (cNavigationView != null)
{
cNavigationView.setNavigationItemSelectedListener(this);
}
Query mQuery= FirebaseDatabase.getInstance().getReference().child("songs");
mListView= (ListView) findViewById(R.id.canzoni_list);
FirebaseListOptions<Song> mOptions= new FirebaseListOptions.Builder<Song>()
.setLayout(R.layout.song_layout)
.setQuery(mQuery, Song.class)
.setLifecycleOwner(this)
.build();
mAdapter= new FirebaseListAdapter <Song>(mOptions){
#Override
protected void populateView(View v, Song model, int position) {
TextView songName= v.findViewById(R.id.songName);
TextView songAuthor=v.findViewById(R.id.author);
songName.setText(model.getName());
songAuthor.setText(model.getAuthor());
}
};
mListView.setAdapter(mAdapter);
}
#Override
protected void onStart() {
super.onStart();
mAdapter.startListening();
}
#Override
protected void onStop() {
super.onStop();
mAdapter.stopListening();
}
#Override
public boolean onOptionsItemSelected(MenuItem Item)
{
if(cToggle.onOptionsItemSelected(Item))
{
return true;
}
return super.onOptionsItemSelected(Item);
}
#Override
public boolean onNavigationItemSelected(MenuItem Item)
{
int id = Item.getItemId();
Intent intent;
if (id == R.id.preghiere)
{
intent= new Intent(this, Preghiere.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
this.startActivity(intent);
}
else if ( id== R.id.bans)
{
intent= new Intent(this, Bans.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
this.startActivity(intent);
}
else if (id== R.id.canzoni)
{
intent= new Intent(this, this.getClass());
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
this.startActivity(intent);
}
else if (id==R.id.calendario)
{
intent= new Intent(this, Calendario.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
this.startActivity(intent);
}
else if (id== R.id.per_riflettere)
{
intent= new Intent(this, perRiflettere.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
this.startActivity(intent);
}
else if( id== R.id.home)
{
intent= new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
this.startActivity(intent);
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.draw_viewC);
drawer.closeDrawer(GravityCompat.START);
return true;
}
}
layout of the above activity
<android.support.v4.widget.DrawerLayout 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=".Canzoni"
android:id="#+id/draw_viewC">
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/canzoni_list">
</ListView>
<android.support.design.widget.NavigationView
android:layout_width="239dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="#color/white"
android:fitsSystemWindows="true"
app:headerLayout="#layout/header"
app:itemIconTint="#color/black"
app:itemTextColor="#color/black"
app:menu="#menu/drawem_menu"
tools:layout_editor_absoluteX="0dp"
tools:layout_editor_absoluteY="0dp"
tools:ignore="MissingConstraints"
android:id="#+id/nav_viewC"/>
</android.support.v4.widget.DrawerLayout>
Any suggestion on how to fix this?
Edit:
the database looks like this:
both writing and reading rules are true
Edit
I have changed the private names in the Song class so they are the same as the database.
private String Author;
private String Song;
private String Url;
it starts working the problem is that now it displays just the author
Update 2
I this code fetch the user data from firebase and show data into recycled view.
In layout i used constaraint layout you can change it..
display_data.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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="match_parent">
<android.support.v7.widget.RecyclerView
android:id="#+id/rvData"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView>
<TextView
android:id="#+id/dlTvEmpty"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="No Found"
android:textSize="16dp"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
then after row_layout bind into recycler view..
row_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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:padding="10dp">
<TextView
android:id="#+id/rlTvName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Name"
android:textSize="20dp" />
<TextView
android:id="#+id/rlTvEmail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Email"
android:textSize="20dp"
app:layout_constraintTop_toBottomOf="#+id/rlTvName" />
<TextView
android:id="#+id/rlTvPwd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Password"
android:textSize="20dp"
app:layout_constraintTop_toBottomOf="#+id/rlTvEmail" />
</android.support.constraint.ConstraintLayout>
then after make pojo class for user that insert into firebase..
User.java
public class User {
public String name;
public String email;
public String pwd;
// Default constructor required for calls to
// DataSnapshot.getValue(User.class)
public User() {
}
public User(String name, String email,String pwd) {
this.name = name;
this.email = email;
this.pwd=pwd;
}
}
then after make adapter class.
DisplayAllData.java
public class DisplayAllData extends RecyclerView.Adapter<DisplayAllData.ItemViewHolder> {
private List<User> mUserLsit = new ArrayList<>();
private Context mContext;
#Override
public ItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_layout, parent, false);
return new ItemViewHolder(view);
}
public DisplayAllData(Context mContext, List<User> mUserLsit) {
this.mContext = mContext;
this.mUserLsit = mUserLsit;
}
#Override
public void onBindViewHolder(ItemViewHolder holder, int position) {
User user = mUserLsit.get(position);
holder.mTvName.setText(user.name);
holder.mTvEmail.setText(user.email);
holder.mTvPwd.setText(user.pwd);
}
#Override
public int getItemCount() {
return mUserLsit.size();
}
public class ItemViewHolder extends RecyclerView.ViewHolder {
TextView mTvName, mTvEmail, mTvPwd;
public ItemViewHolder(View itemView) {
super(itemView);
mTvEmail = itemView.findViewById(R.id.rlTvEmail);
mTvName = itemView.findViewById(R.id.rlTvName);
mTvPwd = itemView.findViewById(R.id.rlTvPwd);
}
}
}
then after finally make display class to fetch user record from firebase and bind into recyclerview.
DisplayActivity.java
public class DisplayActivity extends AppCompatActivity {
private RecyclerView mRvData;
private DisplayAllData allDataAdapter;
private DatabaseReference mDatabase;
private TextView mTvEmpty;
private FirebaseDatabase mFirebaseInstance;
private List<User> mUserList = new ArrayList<>();
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.display_data);
initView();
}
private void initView() {
mFirebaseInstance = FirebaseDatabase.getInstance();
mDatabase = mFirebaseInstance.getReference("usersDb/UserTable");
mRvData = findViewById(R.id.rvData);
mTvEmpty = findViewById(R.id.dlTvEmpty);
mRvData.setLayoutManager(new LinearLayoutManager(this));
mDatabase.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
mUserList.clear();
for (DataSnapshot dataSnapshot1 : dataSnapshot.getChildren()) {
User user = dataSnapshot1.getValue(User.class);
mUserList.add(user);
}
allDataAdapter = new DisplayAllData(DisplayActivity.this, mUserList);
mRvData.setAdapter(allDataAdapter);
allDataAdapter.notifyDataSetChanged();
if (mUserList.isEmpty())
mTvEmpty.setVisibility(View.VISIBLE);
else
mTvEmpty.setVisibility(View.GONE);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
}
After few experiments with code like change this
songName.setText(model.getName());
songAuthor.setText(model.getAuthor());
to this
songName.setText(model.getURL());
songAuthor.setText(model.getAuthor());
I have learned that the problem was really the names I gave to the privates and the names I gave to the get-methods in the Song class. The names of the privates should be the same as the database fields and the names of the methods should be getYourPrivateName().
In your database, you have a property under the name of the song called myAuthor but in the model class, you have the field named Author, both should be the same.
To solve this, you have two solutions. First one would be to delete all the record from your database and add fresh data according to your model class. Make sure that the properties in your database are added using the name od your field that exist in your model class: myName, myURL, myAuthor and NOT Author, Song, Url.
If you are not in testing mode, then just use annotation in your model class like this:
#PropertyName("Song")
private String myName;
#PropertyName("Url")
private String myURL;
#PropertyName("Author")
private String myAuthor;
According to your edited question, you fileds are incorrect. Please how you Song class should look like:
public class Song {
private String author, song, url;
public Song() {}
public Song(String author, String song, String url) {
this.author = author;
this.song = song;
this.url = url;
}
public String getAuthor() { return author; }
public String getSong() { return song; }
public String getUrl() { return url; }
}
See the fields? Are named with the first letter lower case.
My app has a registration screen for blood donors and the blood type field is a spinner. I save all the donor information in an SQLite database. Now I need to retrieve it and show it for a list showing all the registered blood donors with their blood types.
How can I do that?
I've attached all my code below. The main problems appear in RegisterActivity.java and DonorList.java.
RegisterActivity.java
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.Toast;
public class RegisterActivity extends AppCompatActivity {
EditText edtname, edtnumber;
Spinner spblood;
Button btnregister, btnlist;
public static SQLiteHelper sqLiteHelper;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_register);
init();
Spinner spinner = findViewById(R.id.blood_selector);
// Create an ArrayAdapter using the string array and a default spinner layout
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,
R.array.blood_type, android.R.layout.simple_spinner_item);
// Specify the layout to use when the list of choices appears
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
// Apply the adapter to the spinner
spinner.setAdapter(adapter);
sqLiteHelper = new SQLiteHelper(this, "Donors.sqlite", null, 1);
sqLiteHelper.queryData("CREATE TABLE IF NOT EXISTS DONORS (Id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR, number VARCHAR, blood VARCHAR)");
btnregister.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
try {
sqLiteHelper.insertData(
edtname.getText().toString().trim(),
edtnumber.getText().toString().trim(),
spblood
);
}
catch (Exception e) {
e.printStackTrace();
}
}
});
btnlist.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(RegisterActivity.this, DonorList.class);
startActivity(intent);
}
});
}
private void init() {
edtname = findViewById(R.id.name_input);
edtnumber = findViewById(R.id.numberinput);
spblood = findViewById(R.id.blood_selector);
btnregister = findViewById(R.id.register_button);
btnlist = findViewById(R.id.list_button);
}
}
DonorList.java
import android.database.Cursor;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.widget.ListView;
import android.widget.Spinner;
import java.util.ArrayList;
public class DonorList extends AppCompatActivity {
ListView listView;
ArrayList<Donor> list;
DonorListAdapter adapter = null;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.contacts_list);
list = new ArrayList<>();
adapter = new DonorListAdapter(this, R.layout.activity_main, list);
listView.setAdapter(adapter);
Cursor cursor = RegisterActivity.sqLiteHelper.getData("SELECT * FROM DONORS");
list.clear();
while (cursor.moveToNext()) {
String name = cursor.getString(1);
String number = cursor.getString(2);
String blood = cursor.getString(3);
list.add(new Donor(name, number, blood));
}
adapter.notifyDataSetChanged();
}
}
Donor.java
import android.widget.Spinner;
public class Donor {
private String name;
private String number;
private Spinner blood;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public Spinner getBlood() {
return blood;
}
public void setBlood(Spinner blood) {
this.blood = blood;
}
public Donor(String name, String number, Spinner blood) {
this.name = name;
this.number = number;
this.blood = blood;
}
}
SQLiteHelper.java
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteStatement;
import android.widget.Spinner;
public class SQLiteHelper extends SQLiteOpenHelper {
public SQLiteHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
}
public void queryData(String sql) {
SQLiteDatabase database = getWritableDatabase();
database.execSQL(sql);
}
public void insertData(String name, String number, Spinner blood) {
SQLiteDatabase database = getWritableDatabase();
String sql = "INSERT INTO DONORS (name, number, blood) values (?, ?, ?)";
SQLiteStatement statement = database.compileStatement(sql);
statement.clearBindings();
statement.bindString(1, name);
statement.bindString(2, number);
statement.bindString(3, blood.getSelectedItem().toString());
statement.executeInsert();
}
public Cursor getData(String sql) {
SQLiteDatabase database = getReadableDatabase();
return database.rawQuery(sql, null);
}
}
DonorListAdapter.java
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import java.util.ArrayList;
public class DonorListAdapter extends BaseAdapter {
private Context context;
private int layout;
private ArrayList<Donor> donorList;
public DonorListAdapter(Context context, int layout, ArrayList<Donor> donorList) {
this.context = context;
this.layout = layout;
this.donorList = donorList;
}
#Override
public int getCount() {
return donorList.size();
}
#Override
public Object getItem(int position) {
return donorList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
private class ViewHolder {
TextView txtname, txtnumber, txtblood;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
ViewHolder holder = new ViewHolder();
if (row == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (inflater != null) {
row = inflater.inflate(layout, null);
}
if (row != null) {
holder.txtname = row.findViewById(R.id.name_input);
}
if (row != null) {
holder.txtnumber = row.findViewById(R.id.numberinput);
}
if (row != null) {
holder.txtblood = (TextView) row.findViewById(R.id.blood_selector);
}
if (row != null) {
row.setTag(holder);
}
}
else {
holder = (ViewHolder) row.getTag();
}
Donor donor = donorList.get(position);
holder.txtname.setText(donor.getName());
holder.txtnumber.setText(donor.getNumber());
holder.txtblood.setText(donor.getBlood().toString());
return row;
}
}
activity_main.xml
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.lumen.dayem.blooddonor.MainActivity">
<ListView
android:id="#+id/contacts_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:choiceMode="singleChoice">
</ListView>
</LinearLayout>
activity_register.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:id="#+id/name_input"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/person_name"
android:ems="10"
android:inputType="textCapWords"
android:layout_marginBottom="5sp" />
<EditText
android:id="#+id/numberinput"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/hint"
android:ems="10"
android:inputType="phone"
android:layout_marginBottom="5sp" />
<TextView
android:id="#+id/blood"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/blood_type"
android:layout_marginBottom="10sp"/>
<Spinner
android:id="#+id/blood_selector"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:entries="#array/blood_type"
android:prompt="#string/blood_select"
android:layout_marginBottom="5sp"/>
<Button
android:id="#+id/register_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/register" />
<Button
android:id="#+id/list_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/show_donors" />
</LinearLayout>
contact_item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/contact_name"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="#string/contact_name"
android:textSize="22sp"/>
<TextView
android:id="#+id/contact_number"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textAppearance="?android:textAppearanceSmall"
android:text="#string/contact_number"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginLeft="29sp"
android:layout_marginStart="29sp"
android:layout_marginTop="31sp" />
<TextView
android:id="#+id/contact_blood"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textAppearance="?android:textAppearanceMedium"
android:text="#string/blood_type"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginLeft="300sp"
android:layout_marginStart="300sp"
android:layout_marginTop="30sp"/>
</RelativeLayout>
Your class Donor seems to have a field blood of type Spinner. I changed the type to String because a data class should not contain any Views:
public class Donor
{
private String name;
private String number;
private String blood;
// Getters and Setters here...
public Donor(String name, String number, String blood) {
this.name = name;
this.number = number;
this.blood = blood;
}
}
The SQLiteHelper should have a static getInstance() method so you can avoid having it as a static field in RegisterActivity. Also, I think that the database setup should be encapsulated. The Activity does not need to know anything about the database implementation. So I moved the DDL to the SQLiteHelper's onCreate() and dropped queryData(). For the same reason, I changed getData(String sql) to getDonors(). Lastly, insertData() should take data as parameters not Views. So one should not pass the Spinner but the selected item's value.
My version of SQLiteHelper.java:
public class SQLiteHelper extends SQLiteOpenHelper{
private static SQLiteHelper sqliteHelper;
private static String dbName = "Donors.sqlite";
private static int version = 1;
private static final String CREATE_TABLE_DONORS = "CREATE TABLE IF NOT EXISTS DONORS (Id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR, number VARCHAR, blood VARCHAR)";
/**
* We use the application Context under the hood because this helps to avoid Exceptions
* #param ctx
*/
private SQLiteHelper(Context ctx){
super(ctx.getApplicationContext(), dbName, null, version);
}
/**
* SQLiteHelper as a Singleton
* #param ctx any Context
* #return x
*/
public static SQLiteHelper getInstance(Context ctx)
{
if(sqliteHelper == null){
sqliteHelper = new SQLiteHelper(ctx);
}
return sqliteHelper;
}
#Override
public void onCreate(SQLiteDatabase db)
{
db.execSQL(CREATE_TABLE_DONORS);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
// necessary if you have a new database version
}
public void insertData(String name, String number, String blood) {
SQLiteDatabase database = getWritableDatabase();
String sql = "INSERT INTO DONORS (name, number, blood) values (?, ?, ?)";
SQLiteStatement statement = database.compileStatement(sql);
statement.clearBindings();
statement.bindString(1, name);
statement.bindString(2, number);
statement.bindString(3, blood);
statement.executeInsert();
}
public Cursor getDonors() {
String sql = "SELECT * FROM DONORS";
SQLiteDatabase database = getReadableDatabase();
return database.rawQuery(sql, null);
}
}
The updated RegisterActivity.java (note that I got rid of the local variable spinner and only used spblood):
public class RegisterActivity extends AppCompatActivity
{
private EditText edtname, edtnumber;
private Spinner spblood;
private Button btnregister, btnlist;
private SQLiteHelper sqLiteHelper;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_register);
init();
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,
R.array.blood_type, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spblood.setAdapter(adapter);
sqLiteHelper = SQLiteHelper.getInstance(this);
btnregister.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
try {
sqLiteHelper.insertData(
edtname.getText().toString().trim(),
edtnumber.getText().toString().trim(),
spblood.getSelectedItem().toString()
);
}
catch (Exception e) {
e.printStackTrace();
}
}
});
btnlist.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(RegisterActivity.this, DonorList.class);
startActivity(intent);
}
});
}
private void init() {
edtname = findViewById(R.id.name_input);
edtnumber = findViewById(R.id.numberinput);
spblood = findViewById(R.id.blood_selector);
btnregister = findViewById(R.id.register_button);
btnlist = findViewById(R.id.list_button);
}
}
The changes to DonorList and the Adapter are due to the changes I made to SQLiteHelper and Donor. In addition to that, you need to pass the resource id of the list row to the Adapter's Constructor not the resource id of the Activity's layout. Similarly, the R.id.... values for the TextViews in the list row have to match those in contact_item.xml
DonorList.java
public class DonorList extends AppCompatActivity
{
private ListView listView;
private ArrayList<Donor> list;
private DonorListAdapter adapter = null;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.contacts_list);
list = new ArrayList<>();
adapter = new DonorListAdapter(this, R.layout.contact_item, list);
listView.setAdapter(adapter);
Cursor cursor = SQLiteHelper.getInstance(this).getDonors();
list.clear();
while (cursor.moveToNext()) {
String name = cursor.getString(1);
String number = cursor.getString(2);
String blood = cursor.getString(3);
list.add(new Donor(name, number, blood));
}
adapter.notifyDataSetChanged();
}
}
And finally, the Adapter:
public class DonorListAdapter extends BaseAdapter
{
private Context context;
private int layout;
private ArrayList<Donor> donorList;
public DonorListAdapter(Context context, int layout, ArrayList<Donor> donorList) {
this.context = context;
this.layout = layout;
this.donorList = donorList;
}
#Override
public int getCount() {
return donorList.size();
}
#Override
public Object getItem(int position) {
return donorList.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
private class ViewHolder {
TextView txtname, txtnumber, txtblood;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
if (row == null) {
ViewHolder holder = new ViewHolder();
row = LayoutInflater.from(context).inflate(layout, null);
holder.txtname = (TextView)row.findViewById(R.id.contact_name);
holder.txtnumber = (TextView)row.findViewById(R.id.contact_number);
holder.txtblood = (TextView) row.findViewById(R.id.contact_blood);
row.setTag(holder);
}
ViewHolder viewHolder = (ViewHolder) row.getTag();
Donor donor = donorList.get(position);
viewHolder.txtname.setText(donor.getName());
viewHolder.txtnumber.setText(donor.getNumber());
viewHolder.txtblood.setText(donor.getBlood());
return row;
}
}
Enjoy!
Good Day everyone. I have this code and i face problem in deleting. For example, my list of names are Junko, Gemina and Fukar. If i view each, they show same details. Now, if I delete any of them, ex. I delete Fukar, it will be deleted successfully but when I click on Gemina, the detail that appears is of Junko. If i click Junko, it says "Unfortunately the app stopped working". If I add new Name, ex. Nimrod, It will add successfully, but when i view Nimrod, the detail of Gemina will appear. And if i add another name, Vourin, the data of Gemina will appear its like their ids are interchanged and I think the error is in the delete part. I appreciate any comment. Thanks.
Below is my DBHelper.java
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.DatabaseUtils;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import java.util.ArrayList;
import java.util.HashMap;
public class DBHelper extends SQLiteOpenHelper {
public static final String DATABASE_NAME = "contactdb.sqlite";
public static final String CONTACTS_TABLE_NAME = "mycontacts";
public static final String CONTACTS_COLUMN_ID = "id";
public static final String CONTACTS_COLUMN_STUNAME = "name";
public static final String CONTACTS_COLUMN_STUPHONE = "phone";
public static final String CONTACTS_COLUMN_STUSTREET = "street";
public static final String CONTACTS_COLUMN_STUEMAIL = "email";
public static final String CONTACTS_COLUMN_STUCITY = "place";
private HashMap hp;
public DBHelper(Context context)
{
super(context, DATABASE_NAME , null, 3);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(
"create table mycontacts " +
"(id integer primary key autoincrement, name text,phone text,email text, street text,place text)"
);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS mycontacts");
onCreate(db);
}
public boolean addStudentContact(String contactname,String contactphone,String contactstreet,String contactemail, String contactplace){
/*,*/
SQLiteDatabase db=this.getWritableDatabase();
ContentValues contantValues = new ContentValues();
contantValues.put("name",contactname);
contantValues.put("phone", contactphone);
contantValues.put("street",contactstreet);
contantValues.put("email",contactemail);
contantValues.put("place",contactplace);
db.insert("mycontacts", null, contantValues);
db.close();
return true;
}
public boolean updateStudentContact(Integer contactid,String contactname,String contactphone,String contactstreet,String contactemail, String contactplace)
{
/*,String contactname,*/
SQLiteDatabase db=this.getWritableDatabase();
ContentValues contantValues = new ContentValues();
contantValues.put("name",contactname);
contantValues.put("phone", contactphone);
contantValues.put("street",contactstreet);
contantValues.put("email",contactemail);
contantValues.put("place",contactplace);
db.update("mycontacts", contantValues, "id = ?", new String[]{Integer.toString(contactid)});
db.close();
return true;
}
public Integer deleteContact(Integer id){
SQLiteDatabase db=this.getWritableDatabase();
return db.delete("mycontacts","id = ?",new String[]{Integer.toString(id)});
}
public Cursor getData(int contactid){
SQLiteDatabase db=this.getWritableDatabase();
Cursor res=db.rawQuery("Select * from mycontacts where id = " + contactid + "", null);
return res;
}
public int numberOfRows(){
SQLiteDatabase db=this.getWritableDatabase();
int numRows=(int) DatabaseUtils.queryNumEntries(db,CONTACTS_TABLE_NAME);
return numRows;
}
public ArrayList<Person> getAllStudentContacts(){
ArrayList<Person> arraylist= new ArrayList<>();
SQLiteDatabase db=this.getReadableDatabase();
Cursor cursor=db.rawQuery("Select * from mycontacts",null);
if (cursor.moveToFirst()) {
do {
Person person = new Person();
person.name = cursor.getString(cursor.getColumnIndex(CONTACTS_COLUMN_STUNAME));
person.ID = cursor.getInt(cursor.getColumnIndex(CONTACTS_COLUMN_ID));
arraylist.add(person);
} while (cursor.moveToNext());
}
return arraylist;
}
}
DisplayContact.java
package com.test.ppandey.contactapp;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
public class DisplayContact extends AppCompatActivity {
int from_Where_I_Am_Coming = 0;
private DBHelper mydb;
TextView name;
TextView phone;
TextView email;
TextView street;
TextView place;
int id_To_Update = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_display_contact);
name = (TextView) findViewById(R.id.editTextName);
phone = (TextView) findViewById(R.id.editTextPhone);
email = (TextView) findViewById(R.id.editTextStreet);
street = (TextView) findViewById(R.id.editTextEmail);
place = (TextView) findViewById(R.id.editTextCity);
mydb = new DBHelper(this);
Bundle extras = getIntent().getExtras();
{
int Value = extras.getInt("id");
if (Value > 0) {
//means this is the view part not the add contact part.
Cursor rs = mydb.getData(Value);
id_To_Update = Value;
rs.moveToFirst();
String stuname = rs.getString(rs.getColumnIndex(DBHelper.CONTACTS_COLUMN_STUNAME));
String stuphone = rs.getString(rs.getColumnIndex(DBHelper.CONTACTS_COLUMN_STUPHONE));
String stuemail = rs.getString(rs.getColumnIndex(DBHelper.CONTACTS_COLUMN_STUEMAIL));
String stustreet = rs.getString(rs.getColumnIndex(DBHelper.CONTACTS_COLUMN_STUSTREET));
String stuplace = rs.getString(rs.getColumnIndex(DBHelper.CONTACTS_COLUMN_STUCITY));
if (!rs.isClosed()) {
rs.close();
}
Button b = (Button) findViewById(R.id.button1);
b.setVisibility(View.INVISIBLE);
name.setText((CharSequence) stuname);
name.setFocusable(false);
name.setClickable(false);
phone.setText((CharSequence) stuphone);
phone.setFocusable(false);
phone.setClickable(false);
email.setText((CharSequence) stuemail);
email.setFocusable(false);
email.setClickable(false);
street.setText((CharSequence) stustreet);
street.setFocusable(false);
street.setClickable(false);
place.setText((CharSequence) stuplace);
place.setFocusable(false);
place.setClickable(false);
}
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
Bundle extras = getIntent().getExtras();
if (extras != null) {
int Value = extras.getInt("id");
if (Value > 0) {
getMenuInflater().inflate(R.menu.menu_display_contact, menu);
} else {
getMenuInflater().inflate(R.menu.menu_main, menu);
}
}
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
super.onOptionsItemSelected(item);
switch (item.getItemId()) {
case R.id.Edit_Contact:
Button b = (Button) findViewById(R.id.button1);
b.setVisibility(View.VISIBLE);
name.setEnabled(true);
name.setFocusableInTouchMode(true);
name.setClickable(true);
phone.setEnabled(true);
phone.setFocusableInTouchMode(true);
phone.setClickable(true);
email.setEnabled(true);
email.setFocusableInTouchMode(true);
email.setClickable(true);
street.setEnabled(true);
street.setFocusableInTouchMode(true);
street.setClickable(true);
place.setEnabled(true);
place.setFocusableInTouchMode(true);
place.setClickable(true);
return true;
case R.id.Delete_Contact:
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(R.string.deleteContact)
.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
mydb.deleteContact(id_To_Update);
Toast.makeText(getApplicationContext(), "Deleted Successfully", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
startActivity(intent);
}
})
.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// User cancelled the dialog
}
});
AlertDialog d = builder.create();
d.setTitle("Are you sure ?");
d.show();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
public void saveData(View view) {
/*, */
/* mydb.addContact(name.getText().toString(),email.getText().toString(), street.getText().toString(), place.getText().toString(), phone.getText().toString());
finish();*/
Bundle extras = getIntent().getExtras();
if (extras != null) {
int Value = extras.getInt("id");
if (Value > 0) {
if (mydb.updateStudentContact(id_To_Update, name.getText().toString(), phone.getText().toString(), street.getText().toString(),email.getText().toString(), place.getText().toString())) {
Toast.makeText(getApplicationContext(), "Successfully Updated", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
startActivity(intent);
} else {
Toast.makeText(getApplicationContext(), "Record not updated", Toast.LENGTH_SHORT).show();
}
} else {
if (mydb.addStudentContact(name.getText().toString(), phone.getText().toString(),street.getText().toString(), email.getText().toString(), place.getText().toString())) {
Toast.makeText(getApplicationContext(), "Successfully Added", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getApplicationContext(), "Record not added", Toast.LENGTH_SHORT).show();
}
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
startActivity(intent);
}
}
}
}
MainActivity.java
package com.test.ppandey.contactapp;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
public final static String EXTRA_MESSAGE="MESSAGE";
private ListView objListView;
DBHelper db;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
db=new DBHelper(this);
ArrayList<Person> arrayList=db.getAllStudentContacts();
ArrayAdapter arrayAdapter=new ArrayAdapter(this,android.R.layout.simple_list_item_1,arrayList);
objListView=(ListView)findViewById(R.id.listView1);
objListView.setAdapter(arrayAdapter);
objListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
long id_to_search = id;
Bundle dataBundle = new Bundle();
dataBundle.putLong("id", id_to_search);
Intent intent = new Intent(getApplicationContext(), DisplayContact.class);
intent.putExtras(dataBundle);
startActivity(intent);
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
/* int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);*/
super.onOptionsItemSelected(item);
switch(item.getItemId())
{
case R.id.item1:Bundle dataBundle = new Bundle();
dataBundle.putInt("id", 0);
Intent intent = new Intent(getApplicationContext(),DisplayContact.class);
intent.putExtras(dataBundle);
startActivityForResult(intent, 0);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
db=new DBHelper(this);
ArrayList<Person> arrayList=db.getAllStudentContacts();
ArrayAdapter arrayAdapter=new ArrayAdapter(this,android.R.layout.simple_list_item_1,arrayList);
objListView=(ListView)findViewById(R.id.listView1);
objListView.setAdapter(arrayAdapter);
}
}
activity_display_contact.xml
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/scrollView1"
>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="350dp"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
tools:context="com.test.ppandey.contactapp.DisplayContact">
<EditText
android:id="#+id/editTextName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_marginTop="5dp"
android:layout_marginLeft="82dp"
android:ems="10"
android:inputType="text" >
</EditText>
<EditText
android:id="#+id/editTextEmail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/editTextStreet"
android:layout_below="#+id/editTextStreet"
android:layout_marginTop="22dp"
android:ems="10"
android:inputType="textEmailAddress" />
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/editTextName"
android:layout_alignParentLeft="true"
android:text="#string/name"
android:textAppearance="?android:attr/textAppearanceMedium" />
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/editTextCity"
android:layout_alignParentBottom="true"
android:layout_marginBottom="28dp"
android:onClick="saveData"
android:text="#string/save" />
<TextView
android:id="#+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/editTextEmail"
android:layout_alignLeft="#+id/textView1"
android:text="#string/email"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="#+id/textView5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/editTextPhone"
android:layout_alignLeft="#+id/textView1"
android:text="#string/phone"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="#+id/textView4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/editTextEmail"
android:layout_alignLeft="#+id/textView5"
android:text="#string/street"
android:textAppearance="?android:attr/textAppearanceMedium" />
<EditText
android:id="#+id/editTextCity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignRight="#+id/editTextName"
android:layout_below="#+id/editTextEmail"
android:layout_marginTop="30dp"
android:ems="10"
android:inputType="text" />
<TextView
android:id="#+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/editTextCity"
android:layout_alignBottom="#+id/editTextCity"
android:layout_alignParentLeft="true"
android:layout_toLeftOf="#+id/editTextEmail"
android:text="#string/country"
android:textAppearance="?android:attr/textAppearanceMedium" />
<EditText
android:id="#+id/editTextStreet"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/editTextName"
android:layout_below="#+id/editTextPhone"
android:ems="10"
android:inputType="text" >
<requestFocus />
</EditText>
<EditText
android:id="#+id/editTextPhone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/editTextStreet"
android:layout_below="#+id/editTextName"
android:ems="10"
android:inputType="phone|text" />
</RelativeLayout>
</ScrollView>
Person.java
package com.test.ppandey.contactapp;
/**
* Created by Ariel on 08/03/2016.
*/
public class Person {
public String name;
public long ID;
private Person person; {
name = new String(name);
}
private Person id; {
ID = new long(id);
}
}
I added Person.java and edited MainActivity.java and DBHelper.java
This is your problem:
int id_to_search = position + 1;
You are assuming that the IDs and the positions are in sync. This is only true as long as you do not remove any entries. Instead of using the position to reference an entry, you have to use the ID, as that's immutable.
When you pull the entries from your database, you need to pull the name and the ID, and keep that data in your adapter, so you can reference an entry by its ID.
Some code below (just a skeleton):
1) Create a model for your data
public class Person {
// consider making private and adding accessors
public String name;
public long id;
}
2) when you pull your data, pull the name and the ID (you may expand the Person class and this function to pull additional data):
public List<Person> getAllStudentContacts(){
List<Person> arraylist= new ArrayList<>();
SQLiteDatabase db=this.getReadableDatabase();
Cursor cursor=db.rawQuery("Select * from mycontacts",null);
if (cursor.moveToFirst()) {
do {
Person person = new Person();
person.name = cursor.getString(cursor.getColumnIndex(CONTACTS_COLUMN_STUNAME));
person.id = cursor.getInt(cursor.getColumIndex(CONTACTS_COLUMN_ID));
arraylist.add(prson);
} while (cursor.moveToNext());
}
return arraylist;
}
Then in your adapter you use the ID in the Person object to reference it, instead of the position.
Are you refreshing your "List of Names" from your android App afer every insert/delete?
Maybe by calling getAllStudentContacts() from your code after every insert/delete to refill your List of names of your android app?
Good Luck
I'm pretty new to Java and Android apps, just started several weeks ago, everything went pretty well until now, when I stuck for several hours with a problem I cannot resolve, even with checking dozens of threads here.
I'm working on pretty simple android app that is supposed to show movies and years from a database, with a possibility to add record, show them all, search by a year or title. I stopped on a problem with
no such column _id (code 1): , while compiling SELECT _id, title, year FROM movies
I will be grateful for any help.
There are my files :
MainActivity
package com.example.imdbproject;
import java.util.ArrayList;
import java.util.List;
import android.os.Bundle;
import android.app.Activity;
import android.support.v4.widget.SimpleCursorAdapter;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.ListView;
import android.content.ContentValues;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class MainActivity extends Activity {
ListView moviesList;
Button searchYear;
Button searchTitle;
Button showAll;
Button addbtn;
Cursor cursor;
adapter adapter_ob;
MySQLiteHelper helper_ob;
SQLiteDatabase db_ob;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
InitDataBase();
moviesList = (ListView)findViewById(R.id.listView1);
searchYear = (Button)findViewById(R.id.buttonYear);
searchTitle =(Button)findViewById(R.id.buttonTitle);
addbtn = (Button)findViewById(R.id.buttonAdd);
showAll = (Button)findViewById(R.id.buttonShowAll);
adapter_ob = new adapter(this);
String[] from = { helper_ob.KEY_TITLE, helper_ob.KEY_YEAR };
int[] to = { R.id.tv_title, R.id.tv_year };
//PROBLEM
//cursor = adapter_ob.queryName();
//PROBLEM
//SimpleCursorAdapter cursorAdapter = new SimpleCursorAdapter(this, R.layout.row, cursor, from, to, 1);
/*
moviesList.setAdapter(cursorAdapter);
moviesList.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView arg0, View arg1, int arg2, long arg3) {
Bundle passdata = new Bundle();
Cursor listCursor = (Cursor) arg0.getItemAtPosition(arg2);
int nameId = listCursor.getInt(listCursor.getColumnIndex(helper_ob.KEY_ID));
passdata.putInt("keyid", nameId);
Intent passIntent = new Intent(MainActivity.this,EditActivity.class);
passIntent.putExtras(passdata);
startActivity(passIntent);
}
});
*/
addbtn.setOnClickListener(new OnClickListener()
{
public void onClick(View arg0)
{
Intent addsomemoviesIntent = new Intent(MainActivity.this, AddSomeMovies.class);
startActivity(addsomemoviesIntent);
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public void InitDataBase() {
MySQLiteHelper sqh = new MySQLiteHelper(this);
SQLiteDatabase sqdb = sqh.getWritableDatabase();
long result = sqh.addMovie("movietitle", "year");
}
}
adapter.java
package com.example.imdbproject;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.content.ContentValues;
import android.database.Cursor;
public class adapter {
SQLiteDatabase database_ob;
MySQLiteHelper openHelper_ob;
Context context;
public adapter(Context c)
{
context = c;
}
public adapter openToRead()
{
openHelper_ob = new MySQLiteHelper(context,
MySQLiteHelper.DATABASE_NAME, null, MySQLiteHelper.DATABASE_VERSION);
database_ob = openHelper_ob.getWritableDatabase();
return this;
}
public adapter openToWrite()
{
openHelper_ob = new MySQLiteHelper(context,
MySQLiteHelper.DATABASE_NAME, null, MySQLiteHelper.DATABASE_VERSION);
database_ob = openHelper_ob.getWritableDatabase();
return this;
}
public void Close()
{
database_ob.close();
}
public long insertDetails(String title, String year)
{
ContentValues cv = new ContentValues();
cv.put(MySQLiteHelper.KEY_TITLE, title);
cv.put(MySQLiteHelper.KEY_YEAR, year);
openToWrite();
long val = database_ob.insert(MySQLiteHelper.TABLE_NAME, null, cv);
Close();
return val;
}
public Cursor queryName()
{
String[] cols = { MySQLiteHelper.KEY_ID, MySQLiteHelper.KEY_TITLE,
MySQLiteHelper.KEY_YEAR };
openToWrite();
Cursor c = database_ob.query(MySQLiteHelper.TABLE_NAME, cols, null, null, null, null, null);
return c;
}
public Cursor queryAll(int nameId)
{
String[] cols = { MySQLiteHelper.KEY_ID, MySQLiteHelper.KEY_TITLE, MySQLiteHelper.KEY_YEAR };
openToWrite();
Cursor c = database_ob.query(MySQLiteHelper.TABLE_NAME, cols, MySQLiteHelper.KEY_ID + "=" + nameId, null,null,null,null);
return c;
}
}
MySQLiteHelper
package com.example.imdbproject;
import java.util.LinkedList;
import java.util.List;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
public class MySQLiteHelper extends SQLiteOpenHelper {
public static final String DATABASE_NAME = "movie_data.db";
public static final int DATABASE_VERSION = 1;
public static final String TABLE_NAME = "movies";
public static final String KEY_ID = "_id";
public static final String KEY_TITLE = "title";
public static final String KEY_YEAR = "year";
public static final String SCRIPT = "Create table " + TABLE_NAME + " ("
+ KEY_ID + " integer primary key autoincrement, " + KEY_TITLE
+ " text, " + KEY_YEAR + " text);";
public MySQLiteHelper(Context context)
{
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
public MySQLiteHelper(Context context, String name, CursorFactory factory, int version)
{
super(context, name, factory, version);
}
#Override public void onCreate(SQLiteDatabase db)
{
db.execSQL(SCRIPT);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
db.execSQL("DROP TABLE " + TABLE_NAME);
onCreate(db);
}
public long addMovie(String movietitle, String year){
ContentValues cv = new ContentValues();
cv.put(KEY_TITLE, movietitle);
cv.put(KEY_YEAR, year);
SQLiteDatabase sd = getWritableDatabase();
long result = sd.insert(TABLE_NAME, KEY_TITLE, cv);
return result;
}
}
AddSomeMovies
package com.example.imdbproject;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
public class AddSomeMovies extends Activity {
adapter adapter;
MySQLiteHelper helper;
EditText titleEdit, yearEdit;
Button addButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_add_some_movies);
titleEdit = (EditText)findViewById(R.id.etTitle);
yearEdit = (EditText)findViewById(R.id.etYear);
addButton = (Button)findViewById(R.id.button1);
adapter = new adapter(this);
addButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0)
{
String titleValue = titleEdit.getText().toString();
String yearValue = yearEdit.getText().toString();
long val = adapter.insertDetails(titleValue, yearValue);
finish();
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.add_some_movies, menu);
return true;
}
}
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/black"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<Button
android:id="#+id/buttonShowAll"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/buttonTitle"
android:layout_below="#+id/buttonTitle"
android:text="#string/showall"
/>
<Button
android:id="#+id/buttonYear"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/buttonTitle"
android:layout_alignBottom="#+id/buttonTitle"
android:layout_alignParentRight="true"
android:text="#string/yearsearch"
/>
<Button
android:id="#+id/buttonTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:text="#string/titlesearch"
/>
<Button
android:id="#+id/buttonAdd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/buttonShowAll"
android:layout_alignBottom="#+id/buttonShowAll"
android:layout_toRightOf="#+id/buttonShowAll"
android:text="#string/add"
android:onClick="add" />
<Button
android:id="#+id/buttonOk"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignRight="#+id/buttonYear"
android:layout_below="#+id/buttonYear"
android:enabled="false"
android:onClick="ok"
android:text="#string/ok"
android:visibility="invisible" />
<EditText
android:id="#+id/edittext"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/buttonShowAll"
android:layout_centerHorizontal="true"
android:ems="10"
android:hint="#string/searcheditview" />
<ListView
android:id="#+id/listView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/buttonShowAll"
android:layout_below="#+id/edittext" >
</ListView>
</RelativeLayout>
row.xml
<?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" >
<TextView
android:id="#+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="#+id/tv_year"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp" />
</LinearLayout>
SORTED!
At least I think so. Problem disappeared when I changed database version to 2 from 1. So I can guess that it needs more attention now.
try following
public static final String KEY_ID = BaseColumns._ID;
instead of
public static final String KEY_ID = "_id";