Android - sqlite gridview滞后

时间:2017-06-03 13:18:55

标签: android sqlite gridview android-sqlite

我做过研究,但找不到明确的解释,我知道之前有人问过,但我仍然没有解决方法。

我有一个由sqlite填充的gridView。问题是我的gridView的滚动有滞后。我的代码 -

适配器;

public class FoodListAdapter extends BaseAdapter {

private Context context;
private  int layout;
private ArrayList<Food> foodsList;

public FoodListAdapter(Context context, int layout, ArrayList<Food> foodsList) {
    this.context = context;
    this.layout = layout;
    this.foodsList = foodsList;
}

@Override
public int getCount() {
    return foodsList.size();
}

@Override
public Object getItem(int position) {
    return foodsList.get(position);
}

@Override
public long getItemId(int position) {
    return position;
}

private class ViewHolder{
    CircularImageView imageView;
    TextView txtName, txtPrice;
}

@Override
public View getView(int position, View view, ViewGroup viewGroup) {

    View row = view;
    ViewHolder holder = new ViewHolder();


    if(row == null){
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        row = inflater.inflate(layout, null);

        holder.txtName = (TextView) row.findViewById(R.id.txtName);
        holder.txtPrice = (TextView) row.findViewById(R.id.txtPrice);
        holder.imageView = (CircularImageView) row.findViewById(R.id.imgFood);
        row.setTag(holder);
    }
    else {
        holder = (ViewHolder) row.getTag();
    }

    Food food = foodsList.get(position);

    holder.txtName.setText(food.getName());
    holder.txtPrice.setText(food.getPrice());

    byte[] foodImage = food.getImage();
    Bitmap bitmap = BitmapFactory.decodeByteArray(foodImage, 0, foodImage.length);
    holder.imageView.setImageBitmap(bitmap);

    return row;

}

}

活性;

public class FoodList extends AppCompatActivity {

GridView gridView;
ArrayList<Food> list;
AdapterView adapterView;
FoodListAdapter adapter = null;

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

    sqLiteHelper = new SQLiteHelper(this, "FoodDB.sqlite", null, 1);

    sqLiteHelper.queryData("CREATE TABLE IF NOT EXISTS FOOD(Id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR, price VARCHAR, image BLOB)");

    gridView = (GridView) findViewById(R.id.gridView);
    list = new ArrayList<>();
    adapter = new FoodListAdapter(this, R.layout.food_items, list);
    gridView.setAdapter(adapter);

    gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view,
                                int position, long id) {

            String dataFromGrid;
            dataFromGrid = ((TextView)(view.findViewById(R.id.txtName))).getText().toString();


            Intent i = new Intent(getApplicationContext(), FoodInfo.class);

            i.putExtra("unfromfood",dataFromGrid);
            startActivity(i);


        }
    });

    // get all data from sqlite
    Cursor cursor = sqLiteHelper.getData("SELECT * FROM FOOD");
    list.clear();
    while (cursor.moveToNext()){
        int id = cursor.getInt(0);
        String name = cursor.getString(1);
        String price = cursor.getString(2);
        byte[] image = cursor.getBlob(3);

        list.add(new Food(name, price, image, id));
    }
    adapter.notifyDataSetChanged();




}

@Override
public void onResume(){
    super.onResume();
    Cursor cursor = sqLiteHelper.getData("SELECT * FROM FOOD");
    list.clear();
    while (cursor.moveToNext()){
        int id = cursor.getInt(0);
        String name = cursor.getString(1);
        String price = cursor.getString(2);
        byte[] image = cursor.getBlob(3);

        list.add(new Food(name, price, image, id));
    }
    adapter.notifyDataSetChanged();

}

//Creating The Options Menu
@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;
}

//Option Menu Click Events
@Override
public boolean onOptionsItemSelected(MenuItem item) {
    int id = item.getItemId();
    // Settings
    if (id == R.id.action_add_student) {

        {
            final Intent intent = new Intent();
            intent.setClass(Student.this, MainActivity.class);
            startActivity(intent);
        }

    }

    return true;
}

}

一切正常,但滚动有滞后,任何帮助都会受到赞赏。

修改

public class AddFood extends AppCompatActivity {

EditText edtName, edtPrice;
Button btnChoose, btnAdd, btnList;
CircularImageView imageView;

final int REQUEST_CODE_GALLERY = 999;

public static SQLiteHelper sqLiteHelper;

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

    init();

    sqLiteHelper = new SQLiteHelper(this, "FoodDB.sqlite", null, 1);

    sqLiteHelper.queryData("CREATE TABLE IF NOT EXISTS FOOD(Id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR, price VARCHAR, image BLOB)");

    btnChoose.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            ActivityCompat.requestPermissions(
                    AddFood.this,
                    new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
                    REQUEST_CODE_GALLERY
            );
        }
    });

    //THIS IS WHERE I ADD

    btnAdd.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            try{
                sqLiteHelper.insertData(
                        edtName.getText().toString().trim(),
                        edtPrice.getText().toString().trim(),
                        imageViewToByte(imageView)
                );
                Toast.makeText(getApplicationContext(), "Added successfully!", Toast.LENGTH_SHORT).show();                   
                finish();
            }
            catch (Exception e){
                e.printStackTrace();
            }


        }
    });

}

private byte[] imageViewToByte(ImageView image) {
    Bitmap bitmap = ((BitmapDrawable)image.getDrawable()).getBitmap();
    ByteArrayOutputStream stream = new ByteArrayOutputStream();
    bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
    byte[] byteArray = stream.toByteArray();
    return byteArray;
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {

    if(requestCode == REQUEST_CODE_GALLERY){
        if(grantResults.length >0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
            Intent intent = new Intent(Intent.ACTION_PICK);
            intent.setType("image/*");
            startActivityForResult(intent, REQUEST_CODE_GALLERY);
        }
        else {
            Toast.makeText(getApplicationContext(), "You don't have permission to access file location!", Toast.LENGTH_SHORT).show();
        }
        return;
    }

    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {

    if(requestCode == REQUEST_CODE_GALLERY && resultCode == RESULT_OK && data != null){
        Uri uri = data.getData();

        try {
            InputStream inputStream = getContentResolver().openInputStream(uri);

            Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
            imageView.setImageBitmap(bitmap);

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

    super.onActivityResult(requestCode, resultCode, data);
}

private void init(){
    edtName = (EditText) findViewById(R.id.edtName);
    edtPrice = (EditText) findViewById(R.id.edtPrice);
    btnChoose = (Button) findViewById(R.id.btnChoose);
    btnAdd = (Button) findViewById(R.id.btnAdd);
    btnList = (Button) findViewById(R.id.btnList);
    imageView = (CircularImageView) findViewById(R.id.imageView);
}

}

2 个答案:

答案 0 :(得分:1)

要在滚动期间摆脱延迟,您必须有效地加载图像。您可以做的最好的事情是使用像Glide这样的图像加载库。

只需导入库并替换这些行

byte[] foodImage = food.getImage();
Bitmap bitmap = BitmapFactory.decodeByteArray(foodImage, 0, foodImage.length);
holder.imageView.setImageBitmap(bitmap);

这一个

Glide.with(context)
    .load(food.getImage())
    .into(holder.imageView);

我还建议您阅读Loading Large Bitmaps Efficiently

修改

为了避免回收问题(实际上这不是问题,这是列表视图的工作方式),如果每个项目都有照片,你必须检查它们。

如果是,则使用Glide加载图像,否则设置为null(或您选择的默认图像)。

if (food.getImage() != null && food.getImage().length > 0) {
        Glide.with(context)
                .load(food.getImage())
                .into(holder.imageView);
    }
    else {
        holder.imageView.setImageBitmap(null); //or an image of your choice
    }

答案 1 :(得分:0)

试试这个 这个例子将帮助你很多

public class MainActivity extends Activity {

    public class ImageAdapter extends BaseAdapter {

     private Context mContext;
     ArrayList<String> itemList = new ArrayList<String>();

     public ImageAdapter(Context c) {
      mContext = c; 
     }

     void add(String path){
      itemList.add(path); 
     }

  @Override
  public int getCount() {
   return itemList.size();
  }

  @Override
  public Object getItem(int arg0) {
   // TODO Auto-generated method stub
   return null;
  }

  @Override
  public long getItemId(int position) {
   // TODO Auto-generated method stub
   return 0;
  }

  @Override
  public View getView(int position, View convertView, ViewGroup parent) {
   ImageView imageView;
         if (convertView == null) {  // if it's not recycled, initialize some attributes
             imageView = new ImageView(mContext);
             imageView.setLayoutParams(new GridView.LayoutParams(220, 220));
             imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
             imageView.setPadding(8, 8, 8, 8);
         } else {
             imageView = (ImageView) convertView;
         }

         Bitmap bm = decodeSampledBitmapFromUri(itemList.get(position), 220, 220);

         imageView.setImageBitmap(bm);
         return imageView;
  }

  public Bitmap decodeSampledBitmapFromUri(String path, int reqWidth, int reqHeight) {

   Bitmap bm = null;
   // First decode with inJustDecodeBounds=true to check dimensions
   final BitmapFactory.Options options = new BitmapFactory.Options();
   options.inJustDecodeBounds = true;
   BitmapFactory.decodeFile(path, options);

   // Calculate inSampleSize
   options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

   // Decode bitmap with inSampleSize set
   options.inJustDecodeBounds = false;
   bm = BitmapFactory.decodeFile(path, options); 

   return bm;   
  }

  public int calculateInSampleSize(

   BitmapFactory.Options options, int reqWidth, int reqHeight) {
   // Raw height and width of image
   final int height = options.outHeight;
   final int width = options.outWidth;
   int inSampleSize = 1;

   if (height > reqHeight || width > reqWidth) {
    if (width > height) {
     inSampleSize = Math.round((float)height / (float)reqHeight);    
    } else {
     inSampleSize = Math.round((float)width / (float)reqWidth);    
    }   
   }

   return inSampleSize;    
  }

 }

    ImageAdapter myImageAdapter;

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

        GridView gridview = (GridView) findViewById(R.id.gridview);
        myImageAdapter = new ImageAdapter(this);
        gridview.setAdapter(myImageAdapter);

        String ExternalStorageDirectoryPath = Environment
          .getExternalStorageDirectory()
          .getAbsolutePath();

        String targetPath = ExternalStorageDirectoryPath + "/test/";

        Toast.makeText(getApplicationContext(), targetPath, Toast.LENGTH_LONG).show();
        File targetDirector = new File(targetPath);

        File[] files = targetDirector.listFiles();
        for (File file : files){
         myImageAdapter.add(file.getAbsolutePath());
        } 
    }

}