【发布时间】:2017-03-15 20:32:16
【问题描述】:
我有一个显示 8 个图像的活动,所以我不得不使用此代码来避免 outOfMemory,这在某些情况下可以正常工作。
public static 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) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) >= reqHeight
&& (halfWidth / inSampleSize) >= reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);
}
这在这个布局上很好用
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:weightSum="1"
android:layout_width="match_parent"
android:padding="10dp"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context="com.fahrul.pesantrenbahrululum.FotoPerdivisi"
android:orientation="vertical"
tools:showIn="@layout/app_bar_foto_perdivisi">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<LinearLayout
android:id="@+id/kiriFotoPerdivisi"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:orientation="vertical">
</LinearLayout>
<LinearLayout
android:id="@+id/kananFotoPerdivisi"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:orientation="vertical">
</LinearLayout>
</LinearLayout>
</ScrollView>
</LinearLayout>
这里是java代码
public class FotoPerdivisi extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener, ImageView.OnClickListener{
LinearLayout kiriLay, kananLay;
public int[] imageIds={
R.drawable.foto_perdivisi1,R.drawable.foto_perdivisi2,R.drawable.foto_perdivisi3,R.drawable.foto_perdivisi4,
R.drawable.foto_perdivisi5,R.drawable.foto_perdivisi6,R.drawable.foto_perdivisi7
};
public int[] Ids={
R.id.img1,R.id.img2,R.id.img3,R.id.img4,R.id.img5,R.id.img6,R.id.img7
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_foto_perdivisi);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbarFotoPerdivisi);
setSupportActionBar(toolbar);
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_foto_perdivisi);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_foto_perdivisi);
navigationView.setNavigationItemSelectedListener(this);
kiriLay = (LinearLayout)findViewById(R.id.kiriFotoPerdivisi);
kananLay = (LinearLayout)findViewById(R.id.kananFotoPerdivisi);
// NavigationView navigationView = (NavigationView) findViewById(R.id.nav_foto_perdivisi);
// navigationView.setNavigationItemSelectedListener(this);
// RecyclerView recyclerView = (RecyclerView)findViewById(R.id.foto_perdivisiGrid);
// recyclerView.setHasFixedSize(true);
// RecyclerView.LayoutManager layoutManager = new GridLayoutManager(getApplicationContext(),2);
// recyclerView.setLayoutManager(layoutManager);
// ArrayList<CreateList> createLists = prepareData();
// MyAdapter adapter = new MyAdapter(getApplicationContext(),createLists);
// recyclerView.setAdapter(adapter);
prepareLayout();
}
public static 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) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) >= reqHeight
&& (halfWidth / inSampleSize) >= reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(res, resId, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(res, resId, options);
}
public void prepareLayout(){
for(int i = 0; i < imageIds.length;i++) {
ImageView img = new ImageView(this);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, (int) (150 * getResources().getDisplayMetrics().density));
img.setLayoutParams(params);
img.setScaleType(ImageView.ScaleType.CENTER_CROP);
img.setOnClickListener(this);
img.setImageBitmap(decodeSampledBitmapFromResource(getResources(),imageIds[i],params.width/2,params.height/2));
img.setId(Ids[i]);
if (i % 2==0) {
kiriLay.addView(img);
} else{
kananLay.addView(img);
}
}
}
@Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_foto_perdivisi);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
if (id == R.id.nav_home) {
Intent intent = new Intent(getApplicationContext(),MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
} else if (id == R.id.nav_daftar) {
Intent intent = new Intent(getApplicationContext(),DaftarIsiActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
} else if (id == R.id.nav_foto) {
Intent intent = new Intent(getApplicationContext(),Gallery.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
} else if (id == R.id.nav_info) {
Intent intent = new Intent(getApplicationContext(),InfoActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
} else if (id == R.id.nav_exit) {
System.exit(0);
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_foto_perdivisi);
drawer.closeDrawer(GravityCompat.START);
return true;
}
@Override
public void onClick(View view) {
Intent intent = new Intent(getApplicationContext(),ImageViewer.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
ImageView img = (ImageView)view;
for(int i = 0; i < Ids.length; i++){
if(img.getId() == Ids[i]) {
intent.putExtra("position", i);
}
}
intent.putExtra("curUse",1);
startActivity(intent);
}
}
但是如果我改变线性布局参数 android:layout_width="0dp" android:layout_weight="0.5" 代码不起作用,我认为这是因为在 layoutParams 中宽度为 0,导致算术错误。 如何避免 outOfMemoryException 并将布局参数保留为 android:layout_width="0dp" android:layout_weight="0.5" ? 感谢您的任何回应
【问题讨论】: