Приложение базы данных перестало работать и не открывается - PullRequest
0 голосов
/ 29 мая 2018

В настоящее время я работаю над приложением Android Studio, которое использует базу данных SQLite, в которой могут храниться записи о покупках автомобиля, и приложение останавливается, как только нажимается кнопка ADD.Видимо, есть нулевая ссылка на объект.Приложение имеет функцию MainActivity, в которой есть кнопка «Добавить», позволяющая пользователю добавлять записи в базу данных клиентов.При нажатии приложение должно перейти к CustomerRcrdActivity, чтобы разрешить записи в базе данных, оттуда пользователь должен иметь возможность добавлять, просматривать, обновлять или удалять записи, все почему запись должна отображаться на экране.

Я учусьКак создавать приложения для Android, так что будьте добры.Я не прошу вас что-либо сделать для меня, но, пожалуйста, укажите мне правильное направление.Я везде искал ввод, но боюсь, что пропускаю логическую ошибку, я мог бы использовать второй набор глаз.

Буду признателен за любые замечания или советы по этому вопросу.

Большое спасибо,

Ниже приведен код, который, как я подозреваю, может быть ошибочным (я приведуXML на всякий случай, если я сделал что-то нехорошее).

content_main.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"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context=".MainActivity"
tools:showIn="@layout/activity_main">

<TextView
    android:id="@+id/ContentMain_title"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:fontFamily="sans-serif-smallcaps"
    android:text="@string/content_main_title"
    android:textAlignment="center"
    android:textSize="20sp"
    android:textStyle="bold"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintVertical_bias="0.027" />

<Button
    android:id="@+id/button_CR_add"
    android:layout_width="112dp"
    android:layout_height="wrap_content"
    android:layout_marginBottom="416dp"
    android:layout_marginEnd="8dp"
    android:layout_marginTop="7dp"
    android:onClick="buttonClicked"
    android:text="@string/ContentMain_button_CD_add"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintHorizontal_bias="0.054"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/ContentMain_title"
    app:layout_constraintVertical_bias="0.022" />

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="486dp"
    android:layout_marginTop="8dp"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/button_CR_add">

    <ListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>
</android.support.constraint.ConstraintLayout>

XML для CustomerRcrdActivity опущен

CustomerRcrdActivity.java

public class CustomerRcrdActivity extends AppCompatActivity
{

private EditText FName, LName, CarMake, CarModel, CarCost;
private String F_Name;
private String L_Name;
private String Car_Make;
private String Car_Model;
private double d_Car_Cost;
private DatabaseHandler dh;
private dataAdapter da;
private Customer dataModel;
private ListView lv;
private long mId;

//<<<<<<<<<< new class variables
private String original_FName, original_LName, original_CarMake, original_CarModel, original_CarCost;
private boolean mLoaded = false;
private Button mUpdateButton;
private Button mAddButton;
private Button mDeleteButton;
private ArrayList<Customer> mCustomers = new ArrayList<>();
private List<EditText> mAlleditTexts = new ArrayList<>();

@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_customer_rcrd);

    // GET Intent THAT STARTED ACTIVITY
    Intent intent = getIntent();

    // INSTANTIATE DATABASE HANDLER
    dh = new DatabaseHandler(this);

    FName = findViewById(R.id.editText2_FName);
    LName = findViewById(R.id.editText2_LName);
    CarMake = findViewById(R.id.editText2_CarMake);
    CarModel = findViewById(R.id.editText2_CarModel);
    CarCost = findViewById(R.id.editText2_CarCost);
    lv = findViewById(R.id.listView);
    //<<<<<<<<<<< ADDED
    mAlleditTexts.add(FName);
    mAlleditTexts.add(LName);
    mAlleditTexts.add(CarMake);
    mAlleditTexts.add(CarModel);
    mAlleditTexts.add(CarCost);

    //<<<<<<<<<< END OF ADDED

    Button mViewButton = findViewById(R.id.button_CR_view);
    mAddButton = findViewById(R.id.button_CR_add);
    mUpdateButton = findViewById(R.id.button_CR_update);
    mDeleteButton = findViewById(R.id.button_CR_delete);

    mViewButton.setVisibility(View.GONE);                        // never Show and free screen space
    mViewButton.setText(R.string.mViewButton_setText);           // Hijack View Button for clear data
    mViewButton.setVisibility(View.VISIBLE);                     // Show the View (now CLEAR)
    mAddButton.setEnabled(false);                                // Can't click Add as nothing to add
    mUpdateButton.setEnabled(false);                             // Can't click Update nothing to update
    mDeleteButton.setEnabled(false);                             // Can't click Delete as nothing to delete
    setOriginalValues();
    ShowRecords();                                               //<<<< Always show the list no need for View button
    setEditTextFocusChangedListener(mAlleditTexts);
}

//<<<<<<<<<< NEW METHOD
private void setEditTextFocusChangedListener(List<EditText> edit_texts)
{
    for (EditText e: edit_texts)
    {
        e.setOnFocusChangeListener(new View.OnFocusChangeListener()
        {
            @Override
            public void onFocusChange(View view, boolean b)
            {
                if (areOriginalValuesChanged())
                {
                    if (mLoaded)
                    {
                        mUpdateButton.setEnabled(true);
                        mDeleteButton.setEnabled(false);
                        mAddButton.setEnabled(false);
                    } else
                    {

                    }
                } else
                {
                    if (!mLoaded)
                    {
                        mAddButton.setEnabled(true);
                    } else
                    {
                        mAddButton.setEnabled(false);
                    }
                }
            }
        });
    }
}

//<<<<<<<<<< NEW METHOD
private void setOriginalValues()
{
    original_FName = FName.getText().toString();
    original_LName = LName.getText().toString();
    original_CarMake = CarMake.getText().toString();
    original_CarModel = CarModel.getText().toString();
    original_CarCost = CarCost.getText().toString();
}

//<<<<<<<<<< NEW METHOD
private boolean areOriginalValuesChanged()
{
    /*if (original_FName.equals(FName.getText().toString())
            && original_LName.equals(LName.getText().toString())
            && original_CarMake.equals(CarMake.getText().toString())
            && original_CarModel.equals(CarModel.getText().toString())
            && original_CarCost.equals(CarCost.getText().toString())
            )
    {
        return false;
    }
    return true;*/
    return !original_FName.equals(FName.getText().toString())
            || !original_LName.equals(LName.getText().toString())
            || !original_CarMake.equals(CarMake.getText().toString())
            || !original_CarModel.equals(CarModel.getText().toString())
            || !original_CarCost.equals(CarCost.getText().toString());
}

//<<<<<<<<<< NEW METHOD
private void clearEditTexts(List<EditText> editTexts)
{
    for (EditText e: editTexts)
    {
        e.setText("");
    }
    setOriginalValues();
    mLoaded = false;
}

public void buttonClicked(View view)
{
    int id = view.getId();

    switch (id)
    {
        case R.id.button_CR_update:
            // CALL updateCustomer() TO UPDATE CUSTOMER RECORDS
            updateCustomer();
            mLoaded = false;
            break;

        case R.id.button_CR_add:
            // CALL addCustomer() TO ADD TO DATABASE
            addCustomer();
            // CLEAR FIELDS
            clearEditTexts(mAlleditTexts);
            mLoaded = false;
            break;

        case R.id.button_CR_delete:
            // CALL deleteCustomer() TO DELETE CUSTOMER RECORD
            deleteCustomer();
            break;

        case R.id.button_CR_view:
            // CLEAR FIELDS
            clearEditTexts(mAlleditTexts);
            mLoaded = false;
            mAddButton.setEnabled(true);
            mUpdateButton.setEnabled(false);
            mDeleteButton.setEnabled(false);
            break;
    }
    // UPDATE LIST IRRESPECTIVE OF BUTTON CLICKED
    ShowRecords();
}

// UPDATE CUSTOMER RECORD
private void updateCustomer()
{
    getValues();
    if (dh.updateCustomer(dataModel, mId)>0)
    {
        Toast.makeText(getApplicationContext(), "Customer Updated Successfully", Toast.LENGTH_LONG).show();
    } else
    {
        Toast.makeText(getApplicationContext(), "Customer Not Updated", Toast.LENGTH_LONG).show();
    }
}
// INSERT DATA INTO DATABASE
private void addCustomer()
{
    boolean ok_to_add = true;
    // GET VALUES FROM EditText
    getValues();
    if (F_Name == null || F_Name.length() < 1) ok_to_add = false;
    if (L_Name == null || L_Name.length() < 1) ok_to_add = false;
    if (Car_Make == null || Car_Make.length() < 1) ok_to_add = false;
    if (Car_Model == null || Car_Model.length() < 1) ok_to_add = false;
    if (ok_to_add)
    {
        dh.addCustomers(new Customer(F_Name, L_Name, Car_Make, Car_Model, d_Car_Cost));
        Toast.makeText(getApplicationContext(), "Customer Added Successfully", Toast.LENGTH_LONG).show();
    } else
    {
        Toast.makeText(getApplicationContext(), "Unable To Add - Some Data hasn't been given", Toast.LENGTH_LONG).show();
    }
}
// DELETE CUSTOMER RECORD
private void deleteCustomer()
{
    getValues();
    if (dh.deleteCustomer(mId))
    {
        Toast.makeText(getApplicationContext(), "Customer Deleted Successfully", Toast.LENGTH_LONG).show();
    } else
    {
        Toast.makeText(getApplicationContext(), "Customer Not Deleted", Toast.LENGTH_LONG).show();
    }
}

// FUNCTION TO GET VALUES FROM EditText
private void getValues()
{
    F_Name = FName.getText().toString();
    L_Name = LName.getText().toString();
    Car_Make = CarMake.getText().toString();
    Car_Model = CarModel.getText().toString();
    String car_Cost = CarCost.getText().toString();
    if (car_Cost.length() < 1)
    {
        car_Cost = "0.00";
    }
    d_Car_Cost = Double.parseDouble(car_Cost);

}
// RETRIEVE DATA FROM DATABASE & SET TO LIST VIEW
//<<<<<<<<<< CHANGED QUITE A BIT
// Introduced single Customer List with class scope rather than create new list and adapter every time
//      i.e. mCustomers
// Always clear mCustomers and rebuild from database
// if da (the adapter) is null and therefore hasn't been instantiated, instantiate it just once
// otherwise always notify the adapter that the data (mCustomer) has changed
// Added code to the Listener (added just the once now) to set the edit text's to the values
// of the clicked item in the list (load the data)
//  setting flag to say that the data has just been loaded.
//  also setting the original values to the new data
private void ShowRecords()
{
    mCustomers.clear();
    mCustomers.addAll(dh.getAllCustomers());

    if (da == null)
    {
        da = new dataAdapter(this, mCustomers);
        lv.setAdapter(da);

        lv.setOnItemClickListener(new AdapterView.OnItemClickListener()
        {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id)
            {
                dataModel = mCustomers.get(position);
                //<<<<<<<<<< Added
                FName.setText(dataModel.getFName());
                LName.setText(dataModel.getLName());
                CarMake.setText(dataModel.get_CarMake());
                CarModel.setText(dataModel.get_CarModel());
                CarCost.setText(String.valueOf(dataModel.get_CarCost()));
                mLoaded = true;
                setOriginalValues();
                mDeleteButton.setEnabled(true);
                mUpdateButton.setEnabled(false);
                mAddButton.setEnabled(false);
                mId = dataModel.getID();
                //<<<<<<<<<< End of Added
                Toast.makeText(getApplicationContext(), String.valueOf(dataModel.getID()), Toast.LENGTH_SHORT).show();
            }
        });
    } else
    {
        da.notifyDataSetChanged();
    }
}
}

DatabaseHandler.java

public class DatabaseHandler extends SQLiteOpenHelper
{
// DATABASE VERSION
private static final int DATABASE_VERSION = 1;
// DATABASE NAME
private static final String DATABASE_NAME = "CARDEALER.db";
// CUSTOMER TABLE NAME
public static final String TABLE_CUSTOMERS = "Customers";


// CUSTOMER TABLE COLUMN NAMES
private static final String KEY_ID = "ID";
private static final String KEY_FNAME = "First";
private static final String KEY_LNAME = "Last";
private static final String KEY_CAR_MAKE = "Make";
private static final String KEY_CAR_MODEL = "Model";
private static final String KEY_CAR_COST = "Cost";

DatabaseHandler(Context context)
{
    super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
// CREATE TABLES
@Override
public void onCreate(SQLiteDatabase dh)
{
    String CREATE_TABLE_CUSTOMERS = "CREATE TABLE " + TABLE_CUSTOMERS + "("
            + KEY_ID +" INTEGER PRIMARY KEY,"
            + KEY_FNAME +" TEXT,"
            + KEY_LNAME +" TEXT,"
            + KEY_CAR_MAKE  +" TEXT,"
            + KEY_CAR_MODEL +" TEXT,"
            + KEY_CAR_COST +" NUMERIC" + ")";
    dh.execSQL(CREATE_TABLE_CUSTOMERS);
}
// UPGRADING DATABASE
@Override
public void onUpgrade(SQLiteDatabase dh, int oldVersion, int newVersion)
{
    // DROP OLDER TABLE IF EXISTED
    dh.execSQL("DROP TABLE IF EXISTS " + TABLE_CUSTOMERS);

    // CREATE TABLES AGAIN
    onCreate(dh);
}
/**
 * All CRUD (CREATE, READ, UPDATE, DELETE) OPERATIONS
 */
// INSERT VALUES TO TABLE CUSTOMERS
public void addCustomers(Customer customer)
{
    SQLiteDatabase dh = this.getReadableDatabase();
    ContentValues values = new ContentValues();

    values.put(KEY_FNAME, customer.getFName());
    values.put(KEY_LNAME, customer.getLName() );
    values.put(KEY_CAR_MAKE, customer.get_CarMake());
    values.put(KEY_CAR_MODEL, customer.get_CarModel());
    values.put(KEY_CAR_COST, customer.get_CarCost());

    dh.insert(TABLE_CUSTOMERS, null, values);
    dh.close();
}
/**
 *GETTING ALL CUSTOMERS
 **/
public List<Customer> getAllCustomers()
{
    List<Customer> customerList = new ArrayList<Customer>();
    // SELECT ALL QUERY
    String selectQuery = "SELECT  * FROM " + TABLE_CUSTOMERS;

    SQLiteDatabase dh = this.getWritableDatabase();
    Cursor cursor = dh.rawQuery(selectQuery, null);

    // LOOP THROUGH ALL ROWS & ADD TO LIST
    if (cursor.moveToFirst())
    {
        do {
            Customer customer = new Customer();
            customer.setID(Integer.parseInt(cursor.getString(0)));
            customer.setFName(cursor.getString(1));
            customer.setLName(cursor.getString(2));
            customer.set_CarMake(cursor.getString(3));
            customer.set_CarModel(cursor.getString(4));
            customer.set_CarCost(cursor.getDouble(5));

            // ADDING CUSTOMER TO LIST
            customerList.add(customer);
        } while (cursor.moveToNext());
    }
    // CLOSE OUT RAW QUERY CALL
    cursor.close();
    // RETURN CUSTOMER LIST
    return customerList;
}
/**
 *UPDATING SINGLE CUSTOMER
 **/
public int updateCustomer(Customer customer, long id)
{
    if (customer == null)
    {
        return 0;
    }
    SQLiteDatabase dh = this.getWritableDatabase();

    ContentValues values = new ContentValues();
    values.put(KEY_FNAME, customer.getFName());
    values.put(KEY_LNAME, customer.getLName());
    values.put(KEY_CAR_MAKE, customer.get_CarMake());
    values.put(KEY_CAR_MODEL, customer.get_CarModel());
    values.put(KEY_CAR_COST, customer.get_CarCost());

    // UPDATING ROW
    return dh.update(TABLE_CUSTOMERS, values, KEY_ID + " = ?",
            new String[] { String.valueOf(id) });
}
/**
 *DELETING SINGLE CUSTOMER
 **/
public boolean deleteCustomer(long Id)
{
    boolean rv = false;
    SQLiteDatabase dh = this.getWritableDatabase();
    rv = (dh.delete(TABLE_CUSTOMERS, KEY_ID + " = ?",
            new String[] { String.valueOf(Id) }) > 0);
    dh.close();
    return rv;
}
}

dataAdapter.java

public class dataAdapter extends ArrayAdapter<Customer>
{


public dataAdapter(Context context, ArrayList<Customer> customers)
{
    super(context, R.layout.list_customers, customers);
    Context context1 = context;
    ArrayList<Customer> mcustomer = customers;
}

public  class  Holder
{
    TextView idV;
    TextView nameFV;
    TextView nameLV;
    TextView carmakeV;
    TextView carmodelV;
    TextView carcostV;
}

@NonNull
@Override
public View getView(int position, View convertView, @NonNull ViewGroup parent)
{
    // GET DATA ITEM FOR THIS POSITION

    Customer data = getItem(position);
    // CHECK IF EXISTING VIEW IS BEING REUSED, OTHERWISE INFLATE VIEW

    // VIEW LOOKUP CACHE STORED IN TAG
    Holder viewHolder;

    if (convertView == null)
    {
        viewHolder = new Holder();
        LayoutInflater inflater = LayoutInflater.from(getContext());
        convertView = inflater.inflate(R.layout.list_customers, parent, false);

        viewHolder.idV = (TextView) convertView.findViewById(R.id.textView3_CustomerID);
        viewHolder.nameFV = (TextView) convertView.findViewById(R.id.textView3_FName);
        viewHolder.nameLV = (TextView) convertView.findViewById(R.id.textView3_LName);
        viewHolder.carmakeV = (TextView) convertView.findViewById(R.id.textView3_CarMake);
        viewHolder.carmodelV = (TextView) convertView.findViewById(R.id.textView3_CarModel);
        viewHolder.carcostV = (TextView) convertView.findViewById(R.id.textView3_CarCost);

        convertView.setTag(viewHolder);
    } else
    {
        viewHolder = (Holder) convertView.getTag();
    }

    viewHolder.nameFV.setText("First Name: " + data.getFName());
    viewHolder.nameLV.setText("Last Name: " + data.getLName());
    viewHolder.carmakeV.setText("Car Make: " + data.get_CarMake());
    viewHolder.carmodelV.setText("Car Model: " + data.get_CarModel());
    viewHolder.carcostV.setText("Car Cost: " + data.get_CarCost());

    // RETURN COMPLETED VIEW TO RENDER ON SCREEN
    return convertView;
}
}

Я включаю MainActivity на случай, если что-то там пропустил.Вот MainActivity.java

public class MainActivity extends AppCompatActivity
{
//public ListView lv;

@Override
protected void onCreate(Bundle savedInstanceState)
{
    // even tried ListView here (R.id.listView....)
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
    fab.setOnClickListener(new View.OnClickListener()
    {
        @Override
        public void onClick(View view)
        {
            Snackbar.make(view, "Please, click ADD button to begin! ", Snackbar.LENGTH_LONG)
                    .setAction("Action", null).show();
        }
    });

}

@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();

    if (id == R.id.action_about)
    {
        // possibly go to another page
        Toast.makeText(MainActivity.this,
                "SQLite Database App", Toast.LENGTH_LONG).show();
        return true;
    }

    return super.onOptionsItemSelected(item);
}

public void buttonClicked(View view)
{
    // START NEW ACTIVITY WHEN ADD BUTTON CLICKED
    Intent intent = new Intent(this, CustomerRcrdActivity.class);
    startActivity(intent);


}
}

Вот журнал Logcat:

05-30 09:02:03.253 30145-30145/edu.phoenix.mbl402.week4apppp1943_rev1 E/AndroidRuntime: FATAL EXCEPTION: main
Process: edu.phoenix.mbl402.week4apppp1943_rev1, PID: 30145
java.lang.RuntimeException: Unable to start activity ComponentInfo{edu.phoenix.mbl402.week4apppp1943_rev1/edu.phoenix.mbl402.week4apppp1943_rev1.CustomerRcrdActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ListView.setAdapter(android.widget.ListAdapter)' on a null object reference
    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: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ListView.setAdapter(android.widget.ListAdapter)' on a null object reference
    at edu.phoenix.mbl402.week4apppp1943_rev1.CustomerRcrdActivity.ShowRecords(CustomerRcrdActivity.java:276)
    at edu.phoenix.mbl402.week4apppp1943_rev1.CustomerRcrdActivity.onCreate(CustomerRcrdActivity.java:79)
    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) 

Также я включил предложенные модификации, еще раз спасибо!

Ответы [ 2 ]

0 голосов
/ 30 мая 2018

Пример с некоторыми улучшениями / соображениями (возможно)

Приведенный ниже код может дать вам некоторые идеи / приемы и основан на ответах (я включу весь код, который должен помочь вам обойти приложениесбой при запуске).

Первым улучшением является загрузка ListView при запуске Activity.Это было довольно просто, просто вызовите метод ShowRecords.Это устраняет необходимость в кнопке «Просмотр» (см. Позже, как она была поднята).

Однако метод ShowRecords был радикально изменен.Для создания отдельных экземпляров Адаптера и исходного списка клиентов.

В кнопки добавлена ​​логика / интеллект (sic).Те, которые не применимы, выделены серым цветом.- Изначально вы ничего не можете удалить или обновить, вы можете только добавить (добавить, не добавлять, любые данные опущены).- Если вы щелкнете по элементу в списке, эти данные будут загружены в EditTexts, и кнопка «Удалить» - единственная кнопка, которую можно нажать.- Если вы измените значение в EditText, то будет нажата только кнопка «Обновить».

Все действия работают, а также обновляют список (если доступно в соответствии с логикой выше).Таким образом, записи могут быть добавлены, обновлены и удалены.

Кнопка просмотра была нажата, теперь она является кнопкой CLEAR.Это всегда доступно и очищает EditTexts и устанавливает кнопку «Добавить» как доступную (нажатие на элемент списка по-прежнему загружает данные этой записи).

Для облегчения описанного выше были определены некоторые новые переменные класса, а также некоторыебыли перенесены из переменных метода в переменные класса, например, Adapter и Customer List (вы уже объявили da , так что это использовалось).

Подавляющее большинство изменений относится только кCustomerRcrdActivity, хотя в DatabaseHelper были внесены некоторые незначительные изменения ( long для идентификатора, что является правильной практикой, поскольку идентификатор может превышать максимальное значение int ).

В любом случае вот код: -

CustomerRcrdActivity : -

public class CustomerRcrdActivity extends AppCompatActivity {

    private EditText FName, LName, CarMake, CarModel, CarCost;
    private String F_Name;
    private String L_Name;
    private String Car_Make;
    private String Car_Model;
    private double d_Car_Cost;
    private DatabaseHandler dh;
    private dataAdapter da;
    private Customer dataModel;
    private ListView lv;
    private long mId;

    //<<<<<<<<<< new class variables
    private String original_FName, original_LName, original_CarMake, original_CarModel, original_CarCost;
    private boolean mLoaded = false;
    private Button mViewButton, mUpdateButton, mAddButton, mDeleteButton;
    private ArrayList<Customer> mCustomers = new ArrayList<>();
    private List<EditText> mAlleditTexts = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_customer_rcrd);

        // GET Intent THAT STARTED ACTIVITY
        Intent intent = getIntent();

        // INSTANTIATE DATABASE HANDLER
        dh = new DatabaseHandler(this);

        FName = (EditText) findViewById(R.id.editText2_FName);
        LName = (EditText) findViewById(R.id.editText2_LName);
        CarMake = (EditText) findViewById(R.id.editText2_CarMake);
        CarModel = (EditText) findViewById(R.id.editText2_CarModel);
        CarCost = (EditText) findViewById(R.id.editText2_CarCost);

        //<<<<<<<<<<< ADDED
        mAlleditTexts.add(FName);
        mAlleditTexts.add(LName);
        mAlleditTexts.add(CarMake);
        mAlleditTexts.add(CarModel);
        mAlleditTexts.add(CarCost);
        lv = (ListView) findViewById(R.id.lv);
        //<<<<<<<<<< END OF ADDED

        mViewButton = (Button) findViewById(R.id.button_CR_view);
        mAddButton = (Button) findViewById(R.id.button_CR_add);
        mUpdateButton = (Button) findViewById(R.id.button_CR_update);
        mDeleteButton = (Button) findViewById(R.id.button_CR_delete);

        mViewButton.setVisibility(View.GONE); // never Show and free screen space
        mViewButton.setText("CLEAR"); // Hijack View Button for clear data
        mViewButton.setVisibility(View.VISIBLE); // Show the View (now CLEAR)
        mAddButton.setEnabled(false); // Can't click Add as nothing to add
        mUpdateButton.setEnabled(false); // Can't click Update nothing to update
        mDeleteButton.setEnabled(false); // Can't click Delete as nothing to delete
        setOriginalValues();
        ShowRecords(); //<<<< Always show the list no need for View button
        setEditTextFocusChangedListener(mAlleditTexts);
    }

    //<<<<<<<<<< NEW METHOD
    private void setEditTextFocusChangedListener(List<EditText> edit_texts) {
        for (EditText e: edit_texts) {

            e.setOnFocusChangeListener(new View.OnFocusChangeListener() {
                @Override
                public void onFocusChange(View view, boolean b) {
                    if (areOriginalValuesChanged()) {
                        if (mLoaded) {
                            mUpdateButton.setEnabled(true);
                            mDeleteButton.setEnabled(false);
                            mAddButton.setEnabled(false);
                        } else {

                        }
                    } else {
                        if (!mLoaded) {
                            mAddButton.setEnabled(true);
                        } else {
                            mAddButton.setEnabled(false);
                        }
                    }
                }
            });
        }
    }

    //<<<<<<<<<< NEW METHOD
    private void setOriginalValues() {
        original_FName = FName.getText().toString();
        original_LName = LName.getText().toString();
        original_CarMake = CarMake.getText().toString();
        original_CarModel = CarModel.getText().toString();
        original_CarCost = CarCost.getText().toString();
    }

    //<<<<<<<<<< NEW METHOD
    private boolean areOriginalValuesChanged() {
        if (original_FName.equals(FName.getText().toString())
                && original_LName.equals(LName.getText().toString())
                && original_CarMake.equals(CarMake.getText().toString())
                && original_CarModel.equals(CarModel.getText().toString())
                && original_CarCost.equals(CarCost.getText().toString())
                ) {
            return false;
        }
        return true;
    }

    //<<<<<<<<<< NEW METHOD
    private void clearEditTexts(List<EditText> editTexts) {
        for (EditText e: editTexts) {
            e.setText("");
        }
        setOriginalValues();
        mLoaded = false;
    }

    public void buttonClicked(View view)
    {
        int id = view.getId();

        switch (id)
        {
            case R.id.button_CR_update:
                // CALL updateCustomer() TO UPDATE CUSTOMER RECORDS
                updateCustomer();
                mLoaded = false;
                break;

            case R.id.button_CR_add:
                // CALL addCustomer() TO ADD TO DATABASE
                addCustomer();
                clearEditTexts(mAlleditTexts);
                mLoaded = false;

                // START NEW ACTIVITY WHEN ADD BUTTON CLICKED
                //Intent intent = new Intent(this, DatabaseHandler.class);
                //startActivity(intent);

                break;

            case R.id.button_CR_delete:
                // CALL deleteCustomer() TO DELETE CUSTOMER RECORD
                deleteCustomer();
                break;

            case R.id.button_CR_view:
                // CALL viewCustomer() TO VIEW CUSTOMER RECORD
                // START NEW ACTIVITY WHEN ADD BUTTON CLICKED
                //Intent intent2 = new Intent(this, CustomerDBActivity.class);
                //startActivity(intent2);

                // CALL showRecords() TO VIEW CUSTOMER RECORD VIA ListView
                clearEditTexts(mAlleditTexts);
                mLoaded = false;
                mAddButton.setEnabled(true);
                mUpdateButton.setEnabled(false);
                mDeleteButton.setEnabled(false);
                break;
        }
        ShowRecords(); // Update the List irrespective of button clicked
    }


    private void updateCustomer()
    {
        getValues();
         if (dh.updateCustomer(dataModel, mId)>0) {
             Toast.makeText(getApplicationContext(), "Customer Updated Successfully", Toast.LENGTH_LONG).show();
         } else {
             Toast.makeText(getApplicationContext(), "Customer Not Updated", Toast.LENGTH_LONG).show();
         }
    }
    // INSERT DATA INTO DATABASE
    private void addCustomer()
    {
        boolean ok_to_add = true;
        getValues();
        if (F_Name == null || F_Name.length() < 1) ok_to_add = false;
        if (L_Name == null || L_Name.length() < 1) ok_to_add = false;
        if (Car_Make == null || Car_Make.length() < 1) ok_to_add = false;
        if (Car_Model == null || Car_Model.length() < 1) ok_to_add = false;
        if (ok_to_add) {
            dh.addCustomers(new Customer(F_Name, L_Name, Car_Make, Car_Model, d_Car_Cost));
            Toast.makeText(getApplicationContext(), "Customer Added Successfully", Toast.LENGTH_LONG).show();
        } else {
            Toast.makeText(getApplicationContext(), "Unable To Add - Some Data hasn't been given", Toast.LENGTH_LONG).show();
        }
    }

    private void deleteCustomer()
    {
        getValues();
         if (dh.deleteCustomer(mId)) {
             Toast.makeText(getApplicationContext(), "Customer Deleted Successfully", Toast.LENGTH_LONG).show();
         } else {
             Toast.makeText(getApplicationContext(), "Customer Not Deleted", Toast.LENGTH_LONG).show();
         }
    }

    // FUNCTION TO GET VALUES FROM EditText
    private void getValues()
    {

        F_Name = FName.getText().toString();
        L_Name = LName.getText().toString();
        Car_Make = CarMake.getText().toString();
        Car_Model = CarModel.getText().toString();
        String car_Cost = CarCost.getText().toString();
        if (car_Cost.length() < 1) {
            car_Cost = "0.00";
        }
        d_Car_Cost = Double.parseDouble(car_Cost);

    }
    // RETRIEVE DATA FROM DATABASE & SET TO LIST VIEW
    //<<<<<<<<<< CHANGED QUITE A BIT
    // Introduced single Customer List with class scope rather than create new list and adapter everytime
    //      i.e. mCustomers
    // Always clear mCustomers and rebuild from database
    // if da (the adapter) is null and therefore hasn't been instantiated, instantiate it just once
    // otherwsie always notify the adapter that the data (mCustomer) has changed
    // Added code to the Listener (added just the once now) to set the edit text's to the values
    // of the clicked item in the list (load the data)
    //  setting flag to say that the data has just been loaded.
    //  also setting the original values to the new data
    private void ShowRecords()
    {
        mCustomers.clear();
        mCustomers.addAll(dh.getAllCustomers());
        //final ArrayList<Customer> customers = new ArrayList<>(dh.getAllCustomers());
        //final Customer customers = new Customer(dh.getAllCustomers());
        if (da == null) {
            da = new dataAdapter(this, mCustomers);
            //final dataAdapter data = new dataAdapter(this, mCustomers); //<<<< Shouldn't create a new adapter everytime

            lv.setAdapter(da);

            lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    dataModel = mCustomers.get(position);
                    //<<<<<<<<<< Added
                    FName.setText(dataModel.getFName());
                    LName.setText(dataModel.getLName());
                    CarMake.setText(dataModel.get_CarMake());
                    CarModel.setText(dataModel.get_CarModel());
                    CarCost.setText(String.valueOf(dataModel.get_CarCost()));
                    mLoaded = true;
                    setOriginalValues();
                    mDeleteButton.setEnabled(true);
                    mUpdateButton.setEnabled(false);
                    mAddButton.setEnabled(false);
                    mId = dataModel.getID();
                    //<<<<<<<<<< End of Added
                    Toast.makeText(getApplicationContext(), String.valueOf(dataModel.getID()), Toast.LENGTH_SHORT).show();
                }
            });
        } else {
            da.notifyDataSetChanged();
        }
    }
}

DataBaseHandler

public class DatabaseHandler extends SQLiteOpenHelper
{
    // DATABASE VERSION
    private static final int DATABASE_VERSION = 1;
    // DATABASE NAME
    private static final String DATABASE_NAME = "Car Dealer";
    // PREFERRED THE NAME "STAR DEALERSHIP CUSTOMER DATABASE"
// CUSTOMER TABLE NAME
    public static final String TABLE_CUSTOMERS = "Customers";


    // CUSTOMER TABLE COLUMN NAMES
    private static final String KEY_ID = "ID";
    private static final String KEY_FNAME = "First";
    private static final String KEY_LNAME = "Last";
    private static final String KEY_CAR_MAKE = "Make";
    private static final String KEY_CAR_MODEL = "Model";
    private static final String KEY_CAR_COST = "Cost";

    DatabaseHandler(Context context)
    {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }
    // CREATE TABLES
    @Override
    public void onCreate(SQLiteDatabase dh)
    {
        String CREATE_TABLE_CUSTOMERS = "CREATE TABLE " + TABLE_CUSTOMERS + "("
                + KEY_ID +" INTEGER PRIMARY KEY,"
                + KEY_FNAME +" TEXT,"
                + KEY_LNAME +" TEXT,"
                + KEY_CAR_MAKE  +" TEXT,"
                + KEY_CAR_MODEL +" TEXT,"
                + KEY_CAR_COST +" NUMERIC" + ")";
        dh.execSQL(CREATE_TABLE_CUSTOMERS);
    }
    // UPGRADING DATABASE
    @Override
    public void onUpgrade(SQLiteDatabase dh, int oldVersion, int newVersion)
    {
        // DROP OLDER TABLE IF EXISTED
        dh.execSQL("DROP TABLE IF EXISTS " + TABLE_CUSTOMERS);

        // CREATE TABLES AGAIN
        onCreate(dh);
    }
    /**
     * All CRUD (CREATE, READ, UPDATE, DELETE) OPERATIONS
     */
// INSERT VALUES TO TABLE CUSTOMERS

    public void addCustomers(Customer customer)
    {
        SQLiteDatabase dh = this.getReadableDatabase();
        ContentValues values = new ContentValues();

        values.put(KEY_FNAME, customer.getFName());
        values.put(KEY_LNAME, customer.getLName() );
        values.put(KEY_CAR_MAKE, customer.get_CarMake());
        values.put(KEY_CAR_MODEL, customer.get_CarModel());
        values.put(KEY_CAR_COST, customer.get_CarCost());

        dh.insert(TABLE_CUSTOMERS, null, values);
        dh.close();
    }
    /**
     *GETTING ALL CUSTOMERS
     **/
    public List<Customer> getAllCustomers()
    {
        List<Customer> customerList = new ArrayList<Customer>();
        // SELECT ALL QUERY
        String selectQuery = "SELECT  * FROM " + TABLE_CUSTOMERS;

        SQLiteDatabase dh = this.getWritableDatabase();
        Cursor cursor = dh.rawQuery(selectQuery, null);

        // LOOP THROUGH ALL ROWS & ADD TO LIST
        if (cursor.moveToFirst())
        {
            do {
                Customer customer = new Customer();
                customer.setID(Integer.parseInt(cursor.getString(0)));
                customer.setFName(cursor.getString(1));
                customer.setLName(cursor.getString(2));
                customer.set_CarMake(cursor.getString(3));
                customer.set_CarModel(cursor.getString(4));
                customer.set_CarCost(cursor.getDouble(5));

                // ADDING CUSTOMER TO LIST
                customerList.add(customer);
            } while (cursor.moveToNext());
        }
        // CLOSE OUT RAW QUERY CALL
        cursor.close();
        // RETURN CUSTOMER LIST
        return customerList;
    }
    /**
     *UPDATING SINGLE CUSTOMER
     **/
    public int updateCustomer(Customer customer, long id)
    {
        if (customer == null) {
            return 0;
        }
        SQLiteDatabase dh = this.getWritableDatabase();

        ContentValues values = new ContentValues();
        values.put(KEY_FNAME, customer.getFName());
        values.put(KEY_LNAME, customer.getLName());
        values.put(KEY_CAR_MAKE, customer.get_CarMake());
        values.put(KEY_CAR_MODEL, customer.get_CarModel());
        values.put(KEY_CAR_COST, customer.get_CarCost());

        // UPDATING ROW
        return dh.update(TABLE_CUSTOMERS, values, KEY_ID + " = ?",
                new String[] { String.valueOf(id) });
    }
    /**
     *DELETING SINGLE CUSTOMER
     **/
    public boolean deleteCustomer(long Id)
    {
        boolean rv = false;
        SQLiteDatabase dh = this.getWritableDatabase();
        rv = (dh.delete(TABLE_CUSTOMERS, KEY_ID + " = ?",
                new String[] { String.valueOf(Id) }) > 0);
        dh.close();
        return rv;
    }
}

Клиент

  • Примечание это, возможно, весьма отличается от вашего, хотя, возможно, довольно близко.Главное, что следует отметить, это то, что CustomerId имеет длину long , в противном случае, если рассматривать CustomerRcrdActivity , оно имитирует ваше.

: -

public class Customer {

    private long CustomerId;
    private String FName;
    private String LName;
    private String CarMake;
    private String CarModel;
    private Double CarCost;

    public Customer(String first_name, String last_name, String make_of_car, String model, Double cost) {
        this.FName = first_name;
        this.LName = last_name;
        this.CarMake = make_of_car;
        this.CarModel = model;
        this.CarCost = cost;
    }

    public Customer() {
    }

    public void setFName(String FName) {
        this.FName = FName;
    }

    public String getFName() {
        return FName;
    }

    public void setLName(String LName) {
        this.LName = LName;
    }

    public String getLName() {
        return LName;
    }

    public void set_CarMake(String carMake) {
        CarMake = carMake;
    }

    public String get_CarMake() {
        return CarMake;
    }

    public void set_CarCost(Double carCost) {
        CarCost = carCost;
    }

    public Double get_CarCost() {
        return CarCost;
    }

    public void set_CarModel(String carModel) {
        CarModel = carModel;
    }

    public String get_CarModel() {
        return CarModel;
    }

    public void setCustomerId(long customerId) {
        CustomerId = customerId;
    }

    public long getCustomerId() {
        return CustomerId;
    }

    public long getID() {
        return this.getCustomerId();
    }

    public void setID(long id) {
        this.setCustomerId(id);
    }
}

Макеты Все макеты должны повторять ваши, поэтому нет необходимости их включать (ваши, вероятно, будут намного лучше, чемте, что используются для этого, минимальны).

MainActivity

Это не что иное, как запуск CustomerRcrdActivity, и, как таковое, очень просто: -

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Intent i = new Intent(this,CustomerRcrdActivity.class);
        startActivity(i);
    }
}
  • Заметка с помощью возврата из CustomerRcrdActivity приведет вас к пустому экрану, и вы больше ничего не сможете сделать.

Макет - это базовый текстовый элемент TextView, генерируемый при создании проекта: -

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>

AndroidManiFest.xml

Опять же, это довольно просто, только что в него были внесены изменения, чтобы иметь раздел активности для CustomerRcrdActivity: -

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <activity android:name=".CustomerRcrdActivity">
    </activity>
</application>

Примечание имя пакета (3-я строка), скорее всего, будет неправильным, если вы использовали вышеизложенное, поэтому его необходимо изменить.

0 голосов
/ 29 мая 2018

Потенциальная проблема 1

Трудно увидеть, что что-то из вашего кода немедленно остановит приложение, то есть, если CustomerRcrdActivity не запущено (при условии, что это не MAIN/ первое действие) , без какого-либо взаимодействия с пользователем.

В этом случае может случиться так, что действие не было определено как действие в мейнфесте ( AndroidManifest.xml ).

Если нет, то вам следует кодироватьВ качестве действия было бы достаточно следующего: -

    <activity android:name=".CustomerRcrdActivity">
    </activity>

Тогда весь манифест будет выглядеть примерно так: (показано, чтобы дать вам представление о том, где разместить код) : -

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="cpa.carpurchases">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".CustomerRcrdActivity">
        </activity>
    </application>
</manifest>

Тестирование

Копирование кода и создание базовых макетов, а также класса клиента и вызов CustomerRcrdActivity непосредственно из основного действия.Ваш код, кажется, в порядке и отображает EditText и кнопки.Однако при этом возникают некоторые проблемы: -

Проблема 2 - Нажатие на кнопку «Просмотр»

При нажатии кнопки «Просмотр» приложение вылетает как переменная ListView lv не был инициализирован, просто объявлен, поэтому он будет нулевым.

Вы получите сообщение об ошибке, например: -

05-29 10:09:29.382 1551-1551/cpa.carpurchases E/AndroidRuntime: FATAL EXCEPTION: main
    java.lang.IllegalStateException: Could not execute method for android:onClick
        at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:389)
        at android.view.View.performClick(View.java:4084)
        at android.view.View$PerformClick.run(View.java:16966)
        at android.os.Handler.handleCallback(Handler.java:615)
        at android.os.Handler.dispatchMessage(Handler.java:92)
        at android.os.Looper.loop(Looper.java:137)
        at android.app.ActivityThread.main(ActivityThread.java:4745)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:511)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
        at dalvik.system.NativeStart.main(Native Method)
     Caused by: java.lang.reflect.InvocationTargetException
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:511)
        at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:384)
        at android.view.View.performClick(View.java:4084) 
        at android.view.View$PerformClick.run(View.java:16966) 
        at android.os.Handler.handleCallback(Handler.java:615) 
        at android.os.Handler.dispatchMessage(Handler.java:92) 
        at android.os.Looper.loop(Looper.java:137) 
        at android.app.ActivityThread.main(ActivityThread.java:4745) 
        at java.lang.reflect.Method.invokeNative(Native Method) 
        at java.lang.reflect.Method.invoke(Method.java:511) 
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 
        at dalvik.system.NativeStart.main(Native Method) 
     Caused by: java.lang.NullPointerException
        at cpa.carpurchases.CustomerRcrdActivity.ShowRecords(CustomerRcrdActivity.java:123)
        at cpa.carpurchases.CustomerRcrdActivity.buttonClicked(CustomerRcrdActivity.java:81)
        at java.lang.reflect.Method.invokeNative(Native Method) 
        at java.lang.reflect.Method.invoke(Method.java:511) 
        at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:384) 
        at android.view.View.performClick(View.java:4084) 
        at android.view.View$PerformClick.run(View.java:16966) 
        at android.os.Handler.handleCallback(Handler.java:615) 
        at android.os.Handler.dispatchMessage(Handler.java:92) 
        at android.os.Looper.loop(Looper.java:137) 
        at android.app.ActivityThread.main(ActivityThread.java:4745) 
        at java.lang.reflect.Method.invokeNative(Native Method) 
        at java.lang.reflect.Method.invoke(Method.java:511) 
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553) 
        at dalvik.system.NativeStart.main(Native Method) 

Исправление для этого просто, вам просто нужна строка, вonCreate метод, что-то вроде: -

    lv = (ListView) findViewById(R.id.lv); // For testing I gave the ListView an id of **lv**.

Нажатие кнопки «Вид» тогда работает нормально (в моде на данный момент, отмечая, что в настоящее время во время тестирования ничего не было добавлено).

Проблема 3 - Нажатие любой из других кнопок

Нажатие любых других результатов кнопки (если ничего не было введено) приводит к исключению NumberFormatException при вызове метода getValues, так какв поле CarCost нет ничегоЧтобы обойти это, я просто добавил: -

    String car_Cost = CarCost.getText().toString(); //<<<<EXISTING CODE
    if (car_Cost.length() < 1) {
        car_Cost = "0.00";
    }
    d_Car_Cost = Double.parseDouble(car_Cost); //<<<< EXISTING CODE

Внедрение этого исправления приводит к: -

  • работе кнопки УДАЛИТЬ и сообщению о том, что запись была удалена (даже если ее нет),
  • кнопка UPDATE приводит к исключению нулевого указателя (обратите внимание, что данные еще не были введены на этом этапе)
  • кнопка ADD завершается ошибкой, так как в манифесте нет записи для обработчика базы данныхучебный класс.Тем не менее, это не может быть добавлено, поскольку это не деятельность.Плюс в том, что он фактически добавляет строки в таблицу (даже если данные не были добавлены).

Исправлено для кнопки DELETE

Метод deleteCustomer былизменен, чтобы вернуть логическое значение, чтобы указать, была ли строка удалена или нет согласно: -

public boolean deleteCustomer(int Id)
{
    boolean rv = false;
    SQLiteDatabase dh = this.getWritableDatabase();
    rv = (dh.delete(TABLE_CUSTOMERS, KEY_ID + " = ?",
            new String[] { String.valueOf(Id) }) > 0);
    dh.close();
    return rv;
}

дополнительно deleteCustomer был изменен на Toast другое сообщение, если ничего не удалено согласно: -

private void deleteCustomer()
{
    getValues();
     if (dh.deleteCustomer(Id)) {
         Toast.makeText(getApplicationContext(), "Customer Deleted Successfully", Toast.LENGTH_LONG).show();
     } else {
         Toast.makeText(getApplicationContext(), "Customer Not Deleted", Toast.LENGTH_LONG).show();
     }
}

Исправление для кнопки ADD

Строки, которые пытаются запустить DatabaseHandler как действие, были закомментированы в соответствии с: -

        case R.id.button_CR_add:
            // CALL addCustomer() TO ADD TO DATABASE
            addCustomer();

            // START NEW ACTIVITY WHEN ADD BUTTON CLICKED
            //Intent intent = new Intent(this, DatabaseHandler.class);
            //startActivity(intent);

            break;

Кроме того, строки не отображаются.Не добавлено, если ничего не было введено. Я изменил метод addCustomer на: -

// INSERT DATA INTO DATABASE
private void addCustomer()
{
    boolean ok_to_add = true;
    getValues();
    if (F_Name == null || F_Name.length() < 1) ok_to_add = false;
    if (L_Name == null || L_Name.length() < 1) ok_to_add = false;
    if (Car_Make == null || Car_Make.length() < 1) ok_to_add = false;
    if (Car_Model == null || Car_Model.length() < 1) ok_to_add = false;
    if (ok_to_add) {
        dh.addCustomers(new Customer(F_Name, L_Name, Car_Make, Car_Model, d_Car_Cost));
        Toast.makeText(getApplicationContext(), "Customer Added Successfully", Toast.LENGTH_LONG).show();
    } else {
        Toast.makeText(getApplicationContext(), "Unable To Add - Some Data hasn't been given", Toast.LENGTH_LONG).show();
    }
}

Теперь можно добавлять данные.

Кнопка «Просмотр» также отображает данные.

Кнопка обновления

Ошибка связана с тем, что переменная dataModel не установлена, если не нажата запись в списке.

Чтобы обойти это, выполните следующие действия.Были использованы изменения кода: -

Метод updateCustomer was был изменен, чтобы возвращать целое число (количество строк обновления): -

/**
 *UPDATING SINGLE CUSTOMER
 **/
public int updateCustomer(Customer customer, int id)
{
    if (customer == null) {
        return 0;
    }
    SQLiteDatabase dh = this.getWritableDatabase();

    ContentValues values = new ContentValues();
    values.put(KEY_FNAME, customer.getFName());
    values.put(KEY_LNAME, customer.getLName());
    values.put(KEY_CAR_MAKE, customer.get_CarMake());
    values.put(KEY_CAR_MODEL, customer.get_CarModel());
    values.put(KEY_CAR_COST, customer.get_CarCost());

    // UPDATING ROW
    return dh.update(TABLE_CUSTOMERS, values, KEY_ID + " = ?",
            new String[] { String.valueOf(id) });
}

, а метод updateCustomer в CustomerRcrdActivity был изменен на Toast другое сообщение, если обновление не было выполнено (всегда в настоящее время), чтобы оно было:-

private void updateCustomer()
{
    getValues();
     if (dh.updateCustomer(dataModel, Id)>0) {
         Toast.makeText(getApplicationContext(), "Customer Updated Successfully", Toast.LENGTH_LONG).show();
     } else {
         Toast.makeText(getApplicationContext(), "Customer Not Updated", Toast.LENGTH_LONG).show();
     }
...