简体   繁体   English

多列 ListView 显示零而不是数据库值

[英]Multi-Column ListView shows zeros instead of database values

I'm making a speedometer app in android studio and everytime the user goes over the saved speed limit his current speed, longitude, latitude and time should be stored in a database.我正在 android studio 中制作一个速度计应用程序,每次用户超过保存的速度限制时,他当前的速度、经度、纬度和时间都应该存储在数据库中。 The user would then be able to view the entries in a list.然后用户将能够查看列表中的条目。 I've created everythinf but the listview(which has 4 columns using an adapter) only shows zeros instead of the database values.我已经创建了everythinf,但列表视图(使用适配器有 4 列)只显示零而不是数据库值。

DATABASE HELPER数据库助手


package com.mortoglou.speedometer;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

import android.database.sqlite.SQLiteOpenHelper;

import androidx.annotation.Nullable;

public class DatabaseHelper extends SQLiteOpenHelper {
    public static final String DATABASE_NAME = "limits_list_final.db";
    public static final String TABLE_NAME = "limits_list";
    public static final String COL1 = "ID";
    public static final String COL2 = "SPEED";
    public static final String COL3 = "LONGITUDE";
    public static final String COL4 = "LATITUDE";
    public static final String COL5 = "TIMESTAMP";


    public DatabaseHelper(@Nullable Context context) {
        super(context, DATABASE_NAME, null, 3);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        String createTable = "CREATE TABLE " + TABLE_NAME + " (ID INTEGER PRIMARY KEY AUTOINCREMENT, " +
                " SPEED TEXT, LONGITUDE TEXT, LATITUDE TEXT, TIMESTAMP TEXT)";
        db.execSQL(createTable);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS TABLE_NAME");
        onCreate(db);
    }

    public boolean addData(float curSpeed, double longitude, double latitude, long timestamp){
        SQLiteDatabase db = this.getWritableDatabase();
        ContentValues contentValues = new ContentValues();
        contentValues.put(COL2, curSpeed);
        contentValues.put(COL3, longitude);
        contentValues.put(COL4, latitude);
        contentValues.put(COL5, timestamp);


        long result = db.insert(TABLE_NAME, null, contentValues);
        if (result == -1) {
            return false;
        } else {
            return true;
        }
    }

    public Cursor getListContents(){
        SQLiteDatabase db = this.getWritableDatabase();
        Cursor data = db.rawQuery("SELECT * FROM " + TABLE_NAME, null);
        return data;
    }

}

MAIN ACTIVITY主要活动


'package com.mortoglou.speedometer;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.Manifest;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity implements LocationListener, PopUP.PopUpListener {

    private TextView textView;
    private String savedSpeedText;
    private Button updateSpeedButton;
    private Button checkLimits;

    DatabaseHelper myDB;

    public double longi;
    public int ch = 1; //choice
    public float savedSpeed;
    public static final String SHARED_PREFS = "sharedprefs";
    public static final String SAVED_SPEED = "savedspeed";

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

        textView = (TextView) findViewById(R.id.textView5);
        updateSpeedButton = (Button) findViewById(R.id.button);
        checkLimits = (Button) findViewById(R.id.button2);

        myDB = new DatabaseHelper(this);

        updateSpeedButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                popUp();


            }
        });

        checkLimits.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //setContentView(R.layout.speed_limits);
                Intent intent = new Intent(MainActivity.this, LimitsList.class);
                startActivity(intent);
            }
        });

        if (ContextCompat.checkSelfPermission(this,
                Manifest.permission.ACCESS_FINE_LOCATION)
                != PackageManager.PERMISSION_GRANTED) {

            int MY_PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION = 0;
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                    MY_PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
        }

        LocationManager lm = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
        lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);

        // this.onLocationChanged(null);
        //savedSpeed();
        loadSpeed();
        updateSpeed();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.speed_menu, menu);
        return true;
    }


    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {

        switch (item.getItemId()) {
            case R.id.speed1:
                ch = 1; // choice 1 = m/s
                return true;
            case R.id.speed2:
                ch = 2; // choice 2 = km/h
                return true;
        }
        return super.onOptionsItemSelected(item);
    }


    @Override
    public void onLocationChanged(Location location) {

        TextView txt = (TextView) this.findViewById(R.id.textView2);
        float curSpeed = location.getSpeed();
        double longitude = location.getLongitude();
        double latitude = location.getLatitude();
        long timestamp = location.getTime();

        if (location == null) {
            txt.setText("NO LOCATION FOUND");
        } else {
            if (curSpeed > 0) {
                if (ch == 1) {
                    txt.setText(String.format(curSpeed + "m/s"));

                } else if (ch == 2) {
                    txt.setText(String.format(curSpeed * 3.6 + "km/h"));
                }
            } else {
                txt.setText("-");
            }
            speedLimit(curSpeed, longi, latitude, timestamp);
        }


    }

    public void savedSpeed() {
        SharedPreferences sharedPreferences = getSharedPreferences(SHARED_PREFS, MODE_PRIVATE);
        SharedPreferences.Editor editor = sharedPreferences.edit();

        editor.putFloat(SAVED_SPEED, savedSpeed);
        editor.apply();

    }

    public void loadSpeed() {
        SharedPreferences sharedPreferences = getSharedPreferences(SHARED_PREFS, MODE_PRIVATE);

        savedSpeedText = String.valueOf(sharedPreferences.getFloat(SAVED_SPEED, 0));

    }

    public void updateSpeed() {
        textView.setText(savedSpeedText);

    }

    public void popUp() {
        PopUP popUP = new PopUP();
        popUP.show(getSupportFragmentManager(), "pop up");
    }

    public void speedLimit(float curSpeed, double longitude, double latitude, long timestamp) {
        if (curSpeed > savedSpeed) {
            Toast.makeText(this, "Ayo you goin too fast", Toast.LENGTH_SHORT).show();
            AddData(curSpeed, longi, latitude, timestamp);

        }

    }


    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {

    }

    @Override
    public void onProviderEnabled(String provider) {

    }

    @Override
    public void onProviderDisabled(String provider) {

    }

    @Override
    public void passText(float speedText) {
        savedSpeed = speedText;
        savedSpeed();
        loadSpeed();
        updateSpeed();
    }

    public void AddData(float curSpeed, double longitude, double latitude, long time) {
        boolean insertData = myDB.addData(curSpeed, longitude, latitude, time);

        if (insertData == true) {
            Toast.makeText(MainActivity.this, "Successfully Entered Data!", Toast.LENGTH_LONG).show();
        } else {
            Toast.makeText(MainActivity.this, "Something went wrong :(.", Toast.LENGTH_LONG).show();
        }
    }
}

(to view content) (查看内容)


    package com.mortoglou.speedometer;

import android.database.Cursor;
import android.os.Bundle;
import android.widget.ArrayAdapter;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.Toast;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

import java.util.ArrayList;

public class LimitsList extends AppCompatActivity {

    DatabaseHelper myDB;
    ArrayList<Entry> entryList;
    ListView listView;
    Entry entry;


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

        //listView = (ListView) findViewById(R.id.limits_list);
        myDB = new DatabaseHelper(this);

        //populate an ArrayList<String> from the database and then view it
        entryList = new ArrayList<>();
        Cursor data = myDB.getListContents();
        if (data.getCount() == 0) {
            Toast.makeText(this, "There are no contents in this list!", Toast.LENGTH_LONG).show();
        } else {
            int i=0;
            while(data.moveToNext()){
                entry = new Entry(data.getFloat(1),data.getDouble(2),data.getDouble(3), data.getLong(4));
                entryList.add(entry);
                //System.out.println(data.getFloat(1)+" "+data.getDouble(2)+" "+data.getDouble(3), data.getLong(4));
                System.out.println(entryList.get(i).getSpeed());
                i++;
            }
            LimitsAdapter adapter = new LimitsAdapter(this, R.layout.final_list_adapter, entryList);
            listView = findViewById(R.id.limits_list);
            listView.setAdapter(adapter);
        }
    }
}


ENTRY入口


    package com.mortoglou.speedometer;

public class Entry {

    private float Speed;
    private double Longitude;
    private double Latitude;
    private long Time;



    public Entry(float speed, double longitude, double latitude, long time){
        speed = Speed;
        longitude = Longitude;
        latitude = Latitude;
        time = Time;
    }

    public float getSpeed() {
        return Speed;
    }

    public void setSpeed(float speed) {
        Speed = speed;
    }

    public double getLongitude() {
        return Longitude;
    }

    public void setLongitude(double longitude) {
        Longitude = longitude;
    }

    public double getLatitude() {
        return Latitude;
    }

    public void setLatitude(double latitude) {
        Latitude = latitude;
    }

    public long getTime() {
        return Time;
    }

    public void setTime(long time) {
        Time = time;
    }
}

ADAPTER适配器



    package com.mortoglou.speedometer;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;

import java.util.ArrayList;

public class LimitsAdapter extends ArrayAdapter<Entry> {

    private LayoutInflater mInflater;
    private ArrayList<Entry> entries;
    private int mViewResourceId;


    public LimitsAdapter(Context context, int textViewResourceId, ArrayList<Entry> entries) {
        super(context, textViewResourceId, entries);
        this.entries = entries;
        mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        mViewResourceId = textViewResourceId;
    }

    public View getView(int position, View convertView, ViewGroup parent) {
        convertView = mInflater.inflate(mViewResourceId, null);

        Entry entry = entries.get(position);


        TextView speed = (TextView) convertView.findViewById(R.id.speed);
        TextView longitude = (TextView) convertView.findViewById(R.id.longitude);
        TextView latitude = (TextView) convertView.findViewById(R.id.latitude);
        TextView timestamp = (TextView) convertView.findViewById(R.id.timestamp);
        speed.setText(Float.toString(entry.getSpeed()));
        longitude.setText(Double.toString((entry.getLongitude())));
        latitude.setText(Double.toString((entry.getLatitude())));
        timestamp.setText(Long.toString(entry.getTime()));


        return convertView;
    }

}

I believe your issue is with the constructor for the Entry object.我相信您的问题与 Entry 对象的构造函数有关。

You have :-你有 :-

public Entry(float speed, double longitude, double latitude, long time){
    speed = Speed;
    longitude = Longitude;
    latitude = Latitude;
    time = Time;
}

which is setting/overwriting the values passed to the constructor with the values held in the Object's variables which will be the default value (0) for the type of the variable, as no value has been assigned.这是使用对象变量中保存的值设置/覆盖传递给构造函数的值,该值将是变量类型的默认值 (0),因为尚未分配任何值。

  • Default Values默认值

    It's not always necessary to assign a value when a field is declared.声明字段时并不总是需要赋值。 Fields that are declared but not initialized will be set to a reasonable default by the compiler.已声明但未初始化的字段将由编译器设置为合理的默认值。 Generally speaking, this default will be zero or null, depending on the data type.一般而言,此默认值将为零或空值,具体取决于数据类型。 Relying on such default values, however, is generally considered bad programming style.然而,依赖这样的默认值通常被认为是糟糕的编程风格。

    The following chart summarizes the default values for the above data types.下图总结了上述数据类型的默认值。

     Data Type Default Value (for fields) byte 0 short 0 int 0 long 0L float 0.0f double 0.0d char '\' String (or any object) null boolean false

    Primitive Data Types 原始数据类型

You should be setting the Object's variables with the values passed.您应该使用传递的值设置对象的变量。 So use :-所以使用:-

public Entry(float speed, double longitude, double latitude, long time){
    Speed = speed;
    Longitude = longitude;
    Latitude = latitude;
    Time = time;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM