问题
I have an application that has a grid with 2 columns and 5 rows. Each cell is an image and a text The application works well on 800x480. (below image)
The problem is when I run the emulator for 960x540 the grid look like this (below image)
Both use drawable-hdpi and layout-hdpi.
Is there any way even an unorthodox to overcome this problem ?
The code for the grid is
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/IdMainCat"
android:layout_width="match_parent"
android:layout_height="fill_parent" >
<!-- Screen Design for Photos
-->
<TextView
android:id="@+id/tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:paddingTop="5dp"
android:text="@string/app_name"
android:textColor="#ffffff"
android:textSize="25sp" />
<ImageButton
android:id="@+id/bLang"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:src="@drawable/gc"
android:layout_margin="2dp"
android:background="@null"
android:text="Button" />
<GridView
android:id="@+id/gridView2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentBottom="true"
android:layout_below="@+id/tv"
android:columnWidth="270dp"
android:gravity="center"
android:numColumns="2"
android:paddingTop="7dp"
android:stretchMode="columnWidth" >
</GridView>
</RelativeLayout>
and the code for the images is
<?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"
android:background="@drawable/gridview_style"
android:layout_marginTop="10dp"
android:layout_margin="10dp">
<ImageView
android:id="@+id/grid_item_image2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:weightSum="0.6"
android:layout_weight="0.8"
android:scaleType="fitXY"
android:src="@drawable/ac" >
</ImageView>
<TextView
android:id="@+id/grid_item_label2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_below="@+id/grid_item_image2"
android:background="#aa000000"
android:gravity="center"
android:text="@+id/label"
android:textColor="#e0f901"
android:textSize="14dp"
android:textStyle="bold" />
</RelativeLayout>
回答1:
I see many anomalies in the code you posted:
fill_parent
has been deprecated since API level 8.
Now, use match_parent
, instead.
weights
aren't effective in RelativeLayouts.
They only work in LinearLayouts and derivates.
android:textSize
should always be in sp, not in dp.
This: android:text="@+id/label"
is totally wrong.
TextViews, as well as ImageViews, are clickable.
And ImageButtons, as well as ImageViews, don't show any text.
You really don't need an ImageButton.
Therefore, to optimize (by reducing the View count), an image can be inserted in a TextView as a compound drawable.
Just assign you onClickListener to the TextView, instead of to the ImageButton.
So, my new version of your layout (home_grid.xml) would be:
<?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"
android:background="@drawable/app_back"
>
<!-- Screen Design for Photos -->
<TextView
android:id="@+id/tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:padding="8dp"
android:drawablePadding="8dp"
android:drawableRight="@drawable/gc"
android:text="@string/app_name"
android:textColor="#ffffff"
android:textSize="24sp"
/>
<GridView
android:id="@+id/gridView2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentBottom="true"
android:layout_below="@+id/tv"
android:columnWidth="270dp"
android:gravity="center"
android:numColumns="2"
android:stretchMode="columnWidth"
android:horizontalSpacing="8dp"
android:verticalSpacing="8dp"
/>
</RelativeLayout>
And the optimized (for performance) layout (home_mobile.xml) for the icons is...
<?xml version="1.0" encoding="utf-8"?>
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/grid_item2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="8dp"
android:background="#a000"
android:drawablePadding="8dp"
android:drawableTop="@drawable/ac"
android:gravity="center"
android:textColor="#fdf0"
android:textSize="16sp"
android:textStyle="bold"
/>
You can set the image in Java (Home.java):
Drawable drw = getResources().getDrawable(R.drawable.ac);
// setCompoundDrawablesWithIntrinsicBounds (int left, int top, int right, int bottom)
myText.setCompoundDrawablesWithIntrinsicBounds (null, drw, null, null);
All this should work nearly out-of-the-box.
Just fix your Java code to match (for setting the compound drawables, the clicks, ...)
But it's really a trivial fixing.
[EDIT]
This is your fixed Home.java - but still the home_mobile
layout has to be fixed...
... For that, I will need your HomeAdapter.java class, too.
package com.tg.sam;
import java.util.ArrayList;
import java.util.Locale;
import com.tg.sam.HomeAdapter;
import android.app.Activity;
import android.app.ActivityGroup;
import android.app.LocalActivityManager;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.graphics.Color;
import android.graphics.Typeface;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.GridView;
import android.widget.ImageButton;
import android.widget.RelativeLayout;
import android.widget.TextView;
public class Home extends Activity implements OnItemClickListener
{
public static SharedPreferences settings = null;
public static SharedPreferences.Editor editor = null;
public static final String PREFS_NAME = "TG_LANG";
GridView gridView = null;
Integer[] images = {};
String[] categories = {};
// ** NO **
//ImageButton lang;
// city, accommodation, food, shopping, fun, health, pcare, pserv, ed, ph;
TGDatabase db = null;
Intent majorlist = null;
RelativeLayout homelayout = null;
Bundle bundle = null;
TextView tv = null;
// String[] categories = new String[] { "Accomodation" , "Food", "Beaches",
// "Tourism" , "Health" , "Places" , "Shopping", "Real Estate"};
/*
* public static Home group; private ArrayList<View> history;
*/
@Override
protected void onPause()
{
super.onPause();
// ** THIS IS REALLY BAD!! **
System.gc();
}
@Override
public void onConfigurationChanged(Configuration newConfig)
{
super.onConfigurationChanged(newConfig);
/*
* Toast.makeText(MajorList.this, "onConfigurationChanged(): " +
* newConfig.toString(), Toast.LENGTH_SHORT).show();
*/
// onCreate(null);
/*
setContentView(R.layout.home_grid);
//homelayout = (RelativeLayout) findViewById(R.id.IdMainCat);
//homelayout.setBackgroundResource(R.drawable.app_back);
*/
// homelayout.setDrawingCacheEnabled(false);
settings = getSharedPreferences(PREFS_NAME, 0);
cbutton();
/* db = new TGDatabase(this);
intialize();
db.close();
String fontPath = "aus.ttf";
Typeface tf = Typeface.createFromAsset(getAssets(), fontPath);
tv.setTypeface(tf);
tv.setTextColor(Color.WHITE);
categories = new String[]
{
getResources().getString(R.string.Lcity),
getResources().getString(R.string.Accommodation),
getResources().getString(R.string.Food),
getResources().getString(R.string.Shopping),
getResources().getString(R.string.Fun),
getResources().getString(R.string.Health),
getResources().getString(R.string.Pcare),
getResources().getString(R.string.Pserv),
getResources().getString(R.string.Education),
getResources().getString(R.string.Phn)
};
images = new Integer[]
{
R.drawable.lc, R.drawable.ac, R.drawable.fd,
R.drawable.sh, R.drawable.fn, R.drawable.hm, R.drawable.pc,
R.drawable.ps, R.drawable.ed, R.drawable.pn
};
gridView = (GridView) findViewById(R.id.gridView2);
gridView.setAdapter(new HomeAdapter(this, categories, images));
gridView.setOnItemClickListener(this);*/
}
private void cbutton() {
String string = "";
Drawable drw = null;
if (settings.getString("lang", "en").equalsIgnoreCase("en"))
{
string="en";
//Language_check(this, "en");
// ** NO **
//lang.setImageResource(R.drawable.gc);
drw = getResources().getDrawable(R.drawable.gc);
}
else
{
//Language_check(this, "el");
string="el";
// ** NO **
//lang.setImageResource(R.drawable.uk);
drw = getResources().getDrawable(R.drawable.uk);
}
tv.setCompoundDrawablesWithIntrinsicBounds (null, null, drw, null);
Locale locale2 = new Locale(string);
Locale.setDefault(locale2);
Configuration config2 = new Configuration();
config2.locale = locale2;
getBaseContext().getResources().updateConfiguration(config2,
getBaseContext().getResources().getDisplayMetrics());
/*
if(getResources().getString(R.string.locale).equalsIgnoreCase("en"))
{
lang.setImageResource(R.drawable.gc);
}
else
{
lang.setImageResource(R.drawable.uk);
}
*/
}
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
// setContentView(R.layout.home_layout);
setContentView(R.layout.home_grid);
// ** NO - You already set it (my update) in the layout file **
//homelayout = (RelativeLayout) findViewById(R.id.IdMainCat);
//homelayout.setBackgroundResource(R.drawable.app_back);
// homelayout.setDrawingCacheEnabled(false);
db = new TGDatabase(this);
intialize();
db.close();
settings = getSharedPreferences(PREFS_NAME, 0);
lbutton();
String fontPath = "aus.ttf";
Typeface tf = Typeface.createFromAsset(getAssets(), fontPath);
tv.setTypeface(tf);
tv.setTextColor(Color.WHITE);
categories = new String[]
{
getResources().getString(R.string.Lcity),
getResources().getString(R.string.Accommodation),
getResources().getString(R.string.Food),
getResources().getString(R.string.Shopping),
getResources().getString(R.string.Fun),
getResources().getString(R.string.Pcare),
getResources().getString(R.string.Pserv),
getResources().getString(R.string.Education),
getResources().getString(R.string.Health),
getResources().getString(R.string.Phn)
};
images = new Integer[]
{
R.drawable.lc,
R.drawable.ac,
R.drawable.fd,
R.drawable.sh,
R.drawable.fn,
R.drawable.pc,
R.drawable.ps,
R.drawable.ed,
R.drawable.hm,
R.drawable.pn
};
gridView = (GridView) findViewById(R.id.gridView2);
gridView.setAdapter(new HomeAdapter(this, categories, images));
gridView.setSelector(new ColorDrawable(Color.TRANSPARENT));
gridView.setCacheColorHint(Color.TRANSPARENT);
gridView.setOnItemClickListener(this);
// this.history = new ArrayList<View>(); group = this;
}
private void lbutton()
{
Drawable drw = null;
if (getResources().getString(R.string.locale).equalsIgnoreCase("en"))
{
// ** NO **
//lang.setImageResource(R.drawable.gc);
drw = getResources().getDrawable(R.drawable.gc);
editor=settings.edit();
editor.putString("lang", "en");
editor.commit();
} else {
// ** NO **
//lang.setImageResource(R.drawable.uk);
drw = getResources().getDrawable(R.drawable.uk);
editor=settings.edit();
editor.putString("lang", "el");
editor.commit();
}
tv.setCompoundDrawablesWithIntrinsicBounds (null, null, drw, null);
/*
* if(getResources().getString(R.string.locale).equals("en")) { // Call
* above method with context & newLocale
* lang.setImageResource(R.drawable.gc); }else{ // Call above method
* with context & newLocale lang.setImageResource(R.drawable.uk); }
*/
}
private void intialize() {
// TODO Auto-generated method stub
/*
* city = (ImageButton) findViewById(R.id.iml); accommodation =
* (ImageButton) findViewById(R.id.ima); food = (ImageButton)
* findViewById(R.id.imfo); shopping = (ImageButton)
* findViewById(R.id.ims); fun = (ImageButton) findViewById(R.id.imfu);
* health = (ImageButton) findViewById(R.id.imh); pcare = (ImageButton)
* findViewById(R.id.impc); pserv = (ImageButton)
* findViewById(R.id.imps); ed = (ImageButton) findViewById(R.id.imed);
* ph = (ImageButton) findViewById(R.id.impn);
*/
// ** NO **
//lang = (ImageButton) findViewById(R.id.bLang);
tv = (TextView) findViewById(R.id.tv);
/*
* city.setOnClickListener(this);
* accommodation.setOnClickListener(this);
* food.setOnClickListener(this); shopping.setOnClickListener(this);
* fun.setOnClickListener(this); health.setOnClickListener(this);
* pcare.setOnClickListener(this); pserv.setOnClickListener(this);
* ed.setOnClickListener(this); ph.setOnClickListener(this);
*/
// ** NO **
//lang.setOnClickListener
tv.setOnClickListener
(
new OnClickListener()
{
public void onClick(View v)
{
Check();
}
}
);
}
/*
* public void onClick(View v) { // TODO Auto-generated method stub switch
* (v.getId()){ case R.id.iml: majorlist = new Intent(this.getBaseContext(),
* MajorList.class); majorlist.putExtra("type",
* getResources().getString(R.string.Lcity)); //startActivity(majorlist);
* break; case R.id.ima: majorlist = new Intent(this.getBaseContext(),
* MajorList.class); majorlist.putExtra("type",
* getResources().getString(R.string.Accommodation));
* //startActivity(majorlist); break; case R.id.imfo: majorlist = new
* Intent(this.getBaseContext(), MajorList.class);
* majorlist.putExtra("type", getResources().getString(R.string.Food));
* //startActivity(majorlist); break; case R.id.ims: majorlist = new
* Intent(this.getBaseContext(), MajorList.class);
* majorlist.putExtra("type",getResources().getString(R.string.Shopping));
* //startActivity(majorlist); break; case R.id.imfu: majorlist = new
* Intent(this.getBaseContext(), MajorList.class);
* majorlist.putExtra("type",getResources().getString(R.string.Fun));
* //startActivity(majorlist); break; case R.id.imh: majorlist = new
* Intent(this.getBaseContext(), MajorList.class);
* majorlist.putExtra("type", getResources().getString(R.string.Health));
* //startActivity(majorlist); break; case R.id.impc: majorlist = new
* Intent(this.getBaseContext(), MajorList.class);
* majorlist.putExtra("type", getResources().getString(R.string.Pcare));
* //startActivity(majorlist); break; case R.id.imps: majorlist = new
* Intent(this.getBaseContext(), MajorList.class);
* majorlist.putExtra("type", getResources().getString(R.string.Pserv));
* //startActivity(majorlist); break; case R.id.imed: majorlist = new
* Intent(this.getBaseContext(), MajorList.class);
* majorlist.putExtra("type", getResources().getString(R.string.Education));
* //startActivity(majorlist); break; case R.id.impn: majorlist = new
* Intent(this.getBaseContext(), MajorList.class);
* majorlist.putExtra("type", getResources().getString(R.string.Phn));
* //startActivity(majorlist); break;
*
* }
*
* //replaceContentView("MajorList", majorlist); Group group =
* (Group)getParent(); group.startChildActivity("MajorList", majorlist);
*
*
* View view = getLocalActivityManager().startActivity("Sales",
* majorlist.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)) .getDecorView();
*
* // replaceView(view);
*
* }
*/
@Override
public void onBackPressed()
{
super.onBackPressed();
Group group = (Group) getParent();
group.onBackPressed();
homelayout.setBackgroundDrawable(null);
}
private void Check()
{
if (settings.getString("lang", "en").equalsIgnoreCase("en"))
{
editor = settings.edit();
editor.putString("lang", "el");
editor.commit();
Language_check(this, "el");
}
else
{
editor = settings.edit();
editor.putString("lang", "en");
editor.commit();
Language_check(this, "en");
}
/*
* if(getResources().getString(R.string.locale).equals("en")) { // Call
* above method with context & newLocale Language_check(this, "el");
* editor=settings.edit(); //editor.putString("lang", "") }else{ // Call
* above method with context & newLocale Language_check(this, "en"); }
*/
}
private void Language_check(Context context, String string)
{
Locale locale2 = new Locale(string);
Locale.setDefault(locale2);
Configuration config2 = new Configuration();
config2.locale = locale2;
getBaseContext().getResources().updateConfiguration(config2,
getBaseContext().getResources().getDisplayMetrics());
Group group = (Group) getParent();
// setContentView(R.layout.home_layout);
// db.getcityDetails().getDatabase().
Intent i = new Intent(this, LayoutTabAct.class);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
group.startActivity(i);
group.onBackPressed();
finish();
// ** THIS IS BAD!! **
System.gc();
// this.destroyActivity();
// Intent Start = new Intent("com.tg.sam.LayoutTabAct");
// startActivity(Start);
// finish();
// setContentView(R.layout.home_layout);
// setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
// setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
}
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3)
{
// startActivity(majorlist);
if (arg2 == 9)
{
majorlist = new Intent(this.getBaseContext(), PhoneList.class);
majorlist.putExtra("type", categories[arg2]);
}
else
{
// replaceContentView("MajorList", majorlist);
majorlist = new Intent(this.getBaseContext(), MajorList.class);
majorlist.putExtra("type", categories[arg2]);
}
Group group = (Group) getParent();
group.startChildActivity("MajorList", majorlist);
// }
}
/*
* public void replaceView(View v) { history.add(v); setContentView(v);
*
* }
*
* public void back() { if (history.size() > 0) {
* history.remove(history.size() - 1); if (history.size() > 0) {
* setContentView(history.get(history.size() - 1)); } else { finish(); } }
* else { finish(); } }
*
* public void backToFirst() { int size = history.size(); while (size > 1) {
* history.remove(size - 1); size = history.size(); }
* setContentView(history.get(0)); }
*
* @Override public void onBackPressed() { Home.group.back(); return; }
*/
}
[EDIT 2]
And, finially, this is your brand new HomeAdapter.java
package com.tg.sam;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable;
import android.graphics.Typeface;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
//import com.mycomics.sam.R;
public class HomeAdapter extends BaseAdapter
{
private Context context;
private final String[] mobileValues;
private Integer[] images;
public HomeAdapter(Context context, String[] mobileValues , Integer[] images)
{
this.context = context;
this.mobileValues = mobileValues;
this.images = images;
}
public View getView(int position, View convertView, ViewGroup parent)
{
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View gridView = null;
if (convertView == null)
{
gridView = new View(context);
// get layout from mobile.xml
gridView = inflater.inflate(R.layout.home_mobile, null);
// set value into textview
/*if (mobile.equals("Accomodation")) {
imageView.setImageResource(R.drawable.miaccomodation);
} else if (mobile.equals("Food")) {
imageView.setImageResource(R.drawable.mifood);
} else if (mobile.equals("Beaches")) {
imageView.setImageResource(R.drawable.mibeach);
} else if (mobile.equals("Tourism")){
imageView.setImageResource(R.drawable.mitourism);
} else if (mobile.equals("Health")) {
imageView.setImageResource(R.drawable.mihealth);
} else if (mobile.equals("Places")) {
imageView.setImageResource(R.drawable.miplace);
} else if (mobile.equals("Shopping")){
imageView.setImageResource(R.drawable.mishopping);
}else if (mobile.equals("Real Estate")){
imageView.setImageResource(R.drawable.mirestate);
}*/
}
else
{
gridView = (View) convertView;
}
TextView textView = (TextView) gridView
.findViewById(R.id.grid_item_label2);
textView.setText(mobileValues[position]);
// custom font for main categories
String fontPath = "aus.ttf";
Typeface tf = Typeface.createFromAsset(context.getAssets(), fontPath);
textView.setTypeface(tf);
String mobile = mobileValues[position];
textView.setText(mobile);
// ** NO **
// set image based on selected text
// ** NO **
//ImageView imageView = (ImageView) gridView
// .findViewById(R.id.grid_item_image2);
//imageView.setImageResource(images[position]);
final Drawable drw =
context.getResources().getDrawable(images[position]);
textView.setCompoundDrawablesWithIntrinsicBounds(null, drw, null, null);
return gridView;
}
public int getCount()
{
return mobileValues.length;
}
public Object getItem(int position)
{
return null;
}
public long getItemId(int position)
{
return 0;
}
}
This one is to be used with the TextView only version of home_mobile.xml (not the one you have put on DropBox).
Now you should have ALL. Test it now and let me know.
[EDIT 3]
I was finally able to make it work.
This is my result.
I didn't have all the resources, so I used what I had handy (note this is an emulated 2.8" ldpi screen, 240*320):
来源:https://stackoverflow.com/questions/23847672/qhd-and-800x480-different-layout-or-drawable-or-both