简体   繁体   中英

Is there a way of displaying all sqlite tables and contents by using listview?

I made a little tool for getting all information from database at runtime. Here is my code:

package com.example.helix.whiffs;

import android.app.Fragment;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.PopupMenu;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class FragmentDatabase extends Fragment{

    private final String LOG_TAG = "FRAGMENTDATABASE";

    DatabaseListener listener;

    int rowHeight = 40;
    String text;

    Button select;
    TextView counter;
    LinearLayout titleBar;
    LinearLayout dataList;
    PopupMenu popup;

    String[] fields;
    int[] colWidths;
    List<String> data;
    HashMap<Integer, String[]> dataItems;
    HashMap<Integer, String> menuItems;

    DBAdapter db;
    public interface DatabaseListener{
        void onload(String table);
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        super.onCreateView(inflater, container, savedInstanceState);
        View v = inflater.inflate(R.layout.fragment_database, container, false);
        select = (Button)v.findViewById(R.id.select);
        counter = (TextView)v.findViewById(R.id.count);
        titleBar = (LinearLayout)v.findViewById(R.id.titles);
        dataList = (LinearLayout) v.findViewById(R.id.list);

        data = new ArrayList<>();
        menuItems = new HashMap<>();
        dataItems = new HashMap<>();

        db = new DBAdapter(getActivity().getApplicationContext());
        data = db.allTables();

        popup = new PopupMenu(getActivity().getApplicationContext(), select);
        for(int i = 0; i < data.size(); i++) {
            popup.getMenu().add(Menu.NONE, i, i, data.get(i));
            menuItems.put(i, data.get(i));
        }

        popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(MenuItem menuItem) {
                dataList.removeAllViews();
                titleBar.removeAllViews();
                dataItems.clear();

                int itemId = menuItem.getItemId();
                String table = menuItems.get(itemId);
                fields = db.allFields(table);
                TextView idField = new TextView(getActivity().getApplicationContext());
                idField.setText(fields[0]);
                titleBar.addView(idField);
                colWidths = new int[fields.length];
                colWidths[0] = 80;
                for(int i = 1; i < fields.length; i++){
                    colWidths[i] = 200;
                    TextView f = new TextView(getActivity().getApplicationContext());
                    String text = fields[i];
                    f.setText(text);
                    titleBar.addView(f);
                }

                dataItems = db.allValues(table);
                counter.setText(String.valueOf(dataItems.size()));

                for(int i = 0; i < dataItems.size(); i++){

                    LinearLayout row = new LinearLayout(getActivity().getApplicationContext());
                    row.setOrientation(LinearLayout.HORIZONTAL);

                    String[] rowData = dataItems.get(i);

                    TextView idf = new TextView(getActivity().getApplicationContext());
                    if(rowData.length != 0) idf.setText(rowData[0]);
                    row.addView(idf);

                    for(int j = 1; j < rowData.length; j++){
                        TextView idf2 = new TextView(getActivity().getApplicationContext());
                        text = rowData[j];
                        row.addView(idf2);

                        if(text != null && text.length() > 9){
                            int length = 18 * text.length();
                            if(colWidths[j] < length) colWidths[j] = length;
                        }
                        idf2.setText(text);
                    }
                    dataList.addView(row);
                }

                for(int j = 0; j < colWidths.length; j++){
                    TextView tv = (TextView) titleBar.getChildAt(j);
                    ViewGroup.LayoutParams vlp = tv.getLayoutParams();
                    vlp.width = colWidths[j];
                    vlp.height = rowHeight;
                    tv.setLayoutParams(vlp);
                }
                for(int i = 0; i < dataItems.size(); i++){
                    LinearLayout rowLayout = (LinearLayout) dataList.getChildAt(i);
                    for(int j = 0; j < colWidths.length; j++){
                        TextView tv = (TextView) rowLayout.getChildAt(j);
                        ViewGroup.LayoutParams vlp = tv.getLayoutParams();
                        vlp.width = colWidths[j];
                        vlp.height = rowHeight;
                        tv.setLayoutParams(vlp);
                    }
                }
                return true;
            }
        });

        select.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                popup.show();
            }
        });
        return v;
    }

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        if (context instanceof FragmentDatabase.DatabaseListener) {
            listener = (FragmentDatabase.DatabaseListener) context;
        } else {
            throw new RuntimeException(context.toString()
                    + " must implement FragmentListener");
        }
    }

    @Override
    public void onDetach() {
        listener = null;
        super.onDetach();
    }
}

Here is important part of my database adapter:

myDbHelper myhelper;

public List<String> allTables(){
        List<String> result = new ArrayList<>();
        SQLiteDatabase db = myhelper.getWritableDatabase();
        Cursor c = db.rawQuery("SELECT name FROM sqlite_master WHERE type = 'table'",null);
        if(c.moveToFirst()){
            while (!c.isAfterLast()){
                result.add(c.getString(0));
                c.moveToNext();
            }
        }
        return result;
    }

    public String[] allFields(String table){
        List<String> result = new ArrayList<>();
        SQLiteDatabase db = myhelper.getWritableDatabase();
        Cursor c = db.query(table, null, null, null, null, null, null);
        return c.getColumnNames();
    }

    public HashMap<Integer, String[]> allValues(String table) {
        HashMap<Integer, String[]> result = new HashMap<>();
        String[] row;

        SQLiteDatabase db = myhelper.getWritableDatabase();
        Cursor c = db.rawQuery("SELECT * FROM "+table, null);
        int columns = c.getColumnCount();
        if(c.moveToFirst()){
            int rowCount = 0;
            while(!c.isAfterLast()){
                row = new String[columns];
                for(int i = 0; i < columns; i++){
                    row[i] = c.getString(i);
                    Log.i(LOG_TAG, "Row add "+String.valueOf(c.getString(i)));
                }
                result.put(rowCount, row);
                rowCount ++;
                c.moveToNext();
            }
        }
        return result;
    }

static class myDbHelper extends SQLiteOpenHelper
    {
    private Context context;

        public myDbHelper(Context context) {
            super(context, DATABASE_NAME, null, DATABASE_Version);
            this.context=context;
            onCreate(this.getWritableDatabase());
        }
    }
}

And finally the layout file for fragment

<?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">
    <LinearLayout
        android:id="@+id/top_bar"
        android:layout_width="match_parent"
        android:layout_height="48dp"
        android:background="#888888"
        android:orientation="horizontal"
        >
        <Button
            android:id="@+id/select"
            android:layout_width="100dp"
            android:layout_height="match_parent"
            android:text="table"/>
        <TextView
            android:id="@+id/count"
            android:layout_width="100dp"
            android:layout_height="match_parent"
            android:text="total"
            android:textSize="24sp"
            android:gravity="center_horizontal"
            android:layout_marginTop="5dp"/>
    </LinearLayout>
    <HorizontalScrollView
        android:layout_below="@+id/top_bar"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"
            >
            <LinearLayout
                android:id="@+id/titles"
                android:background="#777777"
                android:layout_width="match_parent"
                android:layout_height="36dp"
                android:orientation="horizontal">
            </LinearLayout>
            <ScrollView
                android:layout_width="match_parent"
                android:layout_height="match_parent">
                <LinearLayout
                    android:id="@+id/list"
                    android:orientation="vertical"
                    android:layout_width="match_parent"
                    android:layout_height="0dp"
                    android:layout_weight="1">

                </LinearLayout>
            </ScrollView>
        </LinearLayout>
    </HorizontalScrollView>
</RelativeLayout>

This is all done manually (using nested LinearLayouts). Performance is very good on my Huawei p8. If no list- or recyclerview option is not an option, perhaps this code might be useful for someone.

The answer is Yes as :-

I have a tool I call SQLiteInfoAssistant that is designed as a module and will display information and the underlying data for multiple database should they exist.

The information is displayed in 3 ListView. 2 side by side at the top which initially display the Databases in the upper left view and tables in the selected database in the upper right view.

In this initial view various Database information is displayed in the bottom view. eg The path along with various other information obtained via pragma's.

When a table is clicked, the tables for the database are then displayed in the upper left view and the columns in the upper right view. The lower view shows table information name, SQL used to create the table, column count and the count of columns in the primary key.

In either of the above views long clicking a table will then display the actual data (blobs truncated and displayed as hex representation).

Here's some screen shots:-

Database and Tables

  • (note database testDB001 has been clicked as emptydb001 only has android_metadata) :-

在此处输入图片说明

Table and Columns

在此处输入图片说明

Data in a Table

在此处输入图片说明

  • Can be scrolled horizontally and vertically.

Invocation can be as simple as including the module, creating an instance of the SQLiteInformationAssistan t passing the context and then using the show method. However, many customisations can be made as can be seen by the comments in the following invocation code :-

private void tryitout() {
    // Get an SQLiteInformationAssistant instance
    // Note! the show method invokes the Activity
    SQLiteInformationAssistant SIA = new SQLiteInformationAssistant(this);

    // Instance customisation i.e set Display attributes
    //SIA.setBaseBackgroundColour(0xFFFFFFFF);
    //SIA.setHeadingTextColour(0xFFFFFF00);
    //SIA.setDatabaseListHeadingTextColour(0xFFFFFF00);
    //SIA.setTableListHeadingTextColour(0xFF0077FF);
    //SIA.setColumnListHeadingTextColour(0xFF77FF00);

    //SIA.setDatabaseListTextColour(0xFFFFFFFF);
    //SIA.setDatabaseInfoTextColour(0xFFFF0000);
    //SIA.setDatabaseListBackgroundColour(0xFFFFFF00);
    //SIA.setDatabaseInfoBackgroundColour(0xFFFFFF00);
    //SIA.setDatabaseInfoHeadingTextColour(0xFFFF0000);

    //SIA.setTableListTextColour(0xFFFF00FF);
    //SIA.setTableInfoTextcolour(0xFF0000FF);
    //SIA.setTableListBackgroundColour(0xFFFFFF00);
    //SIA.setTableInfoBackgroundColour(0xFFFFFF00);
    //SIA.setTableInfoHeadingTextColour(0xFFFF00FF);

    //SIA.setColumnListTextColour(0xFFFFFF00);
    //SIA.setColumnInfoTextColour(0xFF000000);
    //SIA.setColumnListBackgroundColour(0xFFFFFF00);
    //SIA.setColumnInfoBackgroundColour(0xFFFFFF00);
    //SIA.setColumnInfoHeadingTextColour(0xFF00FF00);

    //SIA.setStringCellBackgroundColour(0xFFEEEEEE);
    //SIA.setStringCellTextColour(0xFF0000FF);
    //SIA.setIntegerCellBackgroundColour(0xFFFF0000);
    //SIA.setIntegerCelltextColour(0XFFFFFFFF);
    //SIA.setDoubleCellBackgroundColour(0xFF00FFFF);
    //SIA.setDoubleCelltextColour(0XFF5555FF);
    //SIA.setBlobCellBackgroundColour(0xFF44FF55);
    //SIA.setBlobCelltextColour(0xFFFFFF00);
    //SIA.setUnkownCelltextColour(0xFFFFFF00);
    //SIA.setUnknownBackgroundCellColour(0xFFFF0000);
    // Note
    //SIA.setBytesToShowInBlob(128);
    SIA.show();
}

I haven't actually published this or made it available but if anyone is interested I can supply the code, this is mainly because I myself rarely use it as it's so easy to just copy a database into one of the freely available SQLite tools (Navicat, DB Browser for Sqlite, SQLite manager etc). The full code would probably be too large to post here though.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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