我想缩放所有ListView项目,但只有一些项目正在缩放。
这是我的see_share_list_page_list_item_1.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="116dp"
android:orientation="horizontal">
<RelativeLayout
android:layout_width="148dp"
android:layout_height="match_parent">
<ImageView
android:id="@+id/ivOfferImage"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:scaleType="fitXY"
android:src="@drawable/ic_launcher"/>
<!--<ImageView
android:id="@+id/ivOfferIcon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:src="@drawable/ic_launcher"/>-->
</RelativeLayout>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:orientation="vertical">
<TextView
android:id="@+id/tvOfferTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:text="Offer title"
android:textColor="#312F30"
android:textSize="17sp"/>
<TextView
android:id="@+id/tvOfferDescription"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/tvOfferTitle"
android:layout_marginTop="5dp"
android:text="Offer description"
android:textColor="#312F30"
android:maxLines="3"
android:textSize="12sp"/>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="@+id/tvOfferDescription">
<ImageView
android:id="@+id/ivOfferPrice"
android:layout_width="20dp"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_gravity="center_vertical"
android:adjustViewBounds="true"
android:contentDescription="image"
android:src="@drawable/ic_launcher"/>
<TextView
android:id="@+id/tvOfferPrice"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignBottom="@id/ivOfferPrice"
android:layout_marginLeft="5dp"
android:layout_toRightOf="@+id/ivOfferPrice"
android:gravity="bottom"
android:text="115"
android:textColor="#38BA60"
android:textSize="26sp"
android:textStyle="bold"/>
<TextView
android:id="@+id/tvOfferPriceHeader"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignBottom="@+id/ivOfferPrice"
android:layout_marginLeft="3dp"
android:layout_toRightOf="@+id/tvOfferPrice"
android:gravity="bottom"
android:text="cur"
android:textColor="#38BA60"
android:textSize="20sp"
android:textStyle="bold"/>
<LinearLayout
android:id="@+id/rlOfferDistance"
android:layout_width="81dp"
android:layout_height="24dp"
android:layout_alignBottom="@id/ivOfferPrice"
android:layout_marginLeft="20dp"
android:layout_toRightOf="@+id/tvOfferPriceHeader"
android:gravity="center"
android:background="#F00">
<ImageView
android:id="@+id/ivOfferMarker"
android:layout_width="11dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginLeft="6dp"
android:adjustViewBounds="true"
android:src="@drawable/ic_launcher"/>
<TextView
android:id="@+id/tvOfferDistance"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginLeft="13dp"
android:gravity="center"
android:text="600"
android:textColor="#FFFFFF"
android:textSize="15sp"/>
<TextView
android:id="@+id/tvOfferDistanceHeader"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
android:layout_marginLeft="3dp"
android:text="m"
android:textColor="#FFFFFF"
android:textSize="15sp"/>
</LinearLayout>
<TextView
android:id="@+id/tvCreateRouteToTheOffer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@id/rlOfferDistance"
android:layout_alignParentRight="true"
android:layout_gravity="center"
android:text="create the route"
android:textColor="#FF3A4A"
android:textSize="12sp"/>
</RelativeLayout>
</RelativeLayout>
</LinearLayout>
这是我的see_share_list_page_1.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="533dp"
android:layout_height="947dp">
<ListView
android:id="@+id/lvOffersOne"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:dividerHeight="24dp"
android:divider="@android:color/transparent"/>
</LinearLayout>
这是我的Test.java
package com.googlion.shield.demonstration;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;
//TODO ignore this
//import com.example.starfishapp.R;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
public class Test extends Activity{
private ListView offersLV;
private List<Map<String, String>> offersList;
private PageScaler pageScaler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.see_share_list_page_1);
initializeFields();
addOffersToList();
setListAdapterForOffersLV();
pageScaler.scaleThePage();
}
private void initializeFields() {
offersLV = (ListView) findViewById(R.id.lvOffersOne);
offersList = new LinkedList<Map<String, String>>();
pageScaler = new PageScaler(Test.this);
}
private void addOffersToList() {
final int LENGTH = 10;
for (int i = 0; i < LENGTH; ++i) {
addOfferToList();
}
}
private void addOfferToList() {
final Map<String, String> M = new HashMap<String, String>();
M.put("Offer title", "Offer title");
M.put("Offer description", "Offer description");
M.put("Offer price", "115");
M.put("Offer distance", "600");
offersList.add(M);
}
private void setListAdapterForOffersLV() {
final ListAdapter LA = getListAdapterForOffersLV();
offersLV.setAdapter(LA);
}
private ListAdapter getListAdapterForOffersLV() {
final Context C = Test.this;
final int RESOURCE = R.layout.see_share_list_page_list_item_1;
final String[] FROM = getOfferHeadersArray();
final int[] TO = getOfferHeadersIdsArray();
return new SimpleAdapter(C, offersList, RESOURCE, FROM, TO);
}
private String[] getOfferHeadersArray() {
final String[] S = new String[4];
S[0] = "Offer title";
S[1] = "Offer description";
S[2] = "Offer price";
S[3] = "Offer distance";
return S;
}
private int[] getOfferHeadersIdsArray() {
final int[] I = new int[4];
I[0] = R.id.tvOfferTitle;
I[1] = R.id.tvOfferDescription;
I[2] = R.id.tvOfferPrice;
I[3] = R.id.tvOfferDistance;
return I;
}
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
pageScaler.scale(offersLV);
}
}
这是我的PageScaler.java
package com.googlion.shield.demonstration;
import static android.R.attr.state_checked;
import static android.R.id.*;
import static android.graphics.Bitmap.*;
import static android.util.DisplayMetrics.*;
import static android.util.StateSet.*;
import static android.util.TypedValue.*;
import static android.view.ViewGroup.LayoutParams.*;
import static java.lang.Math.*;
import android.app.*;
import android.content.res.*;
import android.graphics.*;
import android.graphics.drawable.*;
import android.os.*;
import android.util.*;
import android.view.*;
import android.view.ViewGroup.*;
import android.widget.*;
// TODO ignore this
//import com.example.starfishapp.R;
public class PageScaler {
private Activity requester;
private View currentView;
private LayoutParams currentViewLayoutParameters;
private float scale;
private int originalDrawableResourceId;
private Bundle originalDrawablesResourceIds;
public PageScaler(final Activity REQUESTER) {
requester = REQUESTER;
currentView = getRootViewFromRequester();
currentViewLayoutParameters = currentView.getLayoutParams();
scale = getScaleFromRootViewAndRequester();
originalDrawableResourceId = 0;
originalDrawablesResourceIds = new Bundle();
}
private View getRootViewFromRequester() {
final View V = requester.findViewById(content);
final ViewGroup VG = (ViewGroup) V;
final int ROOT_VIEW_INDEX = 0;
return VG.getChildAt(ROOT_VIEW_INDEX);
}
private float getScaleFromRootViewAndRequester() {
final DisplayMetrics DM = getDisplayMetricsFromRequester();
final float SCREEN_WIDTH = (float) DM.widthPixels;
final float SCREEN_HEIGHT = (float) DM.heightPixels;
final int BASE_DENSITY = DENSITY_LOW;
final float CURRENT_DENSITY = (float) DM.densityDpi;
final float DENSITY_SCALE = CURRENT_DENSITY / BASE_DENSITY;
final float ROOT_WIDTH = currentViewLayoutParameters.width;
final float SCALED_ROOT_WIDTH = ROOT_WIDTH / DENSITY_SCALE;
final float ROOT_HEIGHT = currentViewLayoutParameters.height;
final float SCALED_ROOT_HEIGHT = ROOT_HEIGHT / DENSITY_SCALE;
final float HORIZONTAL_SCALE = SCREEN_WIDTH / SCALED_ROOT_WIDTH;
final float VERTICAL_SCALE = SCREEN_HEIGHT / SCALED_ROOT_HEIGHT;
return min(HORIZONTAL_SCALE, VERTICAL_SCALE) / DENSITY_SCALE;
}
private DisplayMetrics getDisplayMetricsFromRequester() {
final DisplayMetrics DM = new DisplayMetrics();
final WindowManager WM = requester.getWindowManager();
final Display D = WM.getDefaultDisplay();
D.getMetrics(DM);
return DM;
}
public void scaleThePage() {
if (pageIsDefinedToBeScalable()) {
scale();
}
}
private boolean pageIsDefinedToBeScalable() {
boolean b = currentViewWidthIsNotDefinedBySpecialValue();
b &= currentViewHeightIsNotDefinedBySpecialValue();
return b;
}
private boolean currentViewWidthIsNotDefinedBySpecialValue() {
boolean b = currentViewLayoutParameters.width != MATCH_PARENT;
b &= currentViewLayoutParameters.width != WRAP_CONTENT;
return b;
}
private boolean currentViewHeightIsNotDefinedBySpecialValue() {
boolean b = currentViewLayoutParameters.height != MATCH_PARENT;
b &= currentViewLayoutParameters.height != WRAP_CONTENT;
return b;
}
private void scale() {
stretchPageToTheDeviceScreenSize();
scale(currentView);
}
private void stretchPageToTheDeviceScreenSize() {
currentViewLayoutParameters.width = MATCH_PARENT;
currentViewLayoutParameters.height = MATCH_PARENT;
}
public void scale(final View V) {
retrieveCurrentViewFrom(V);
retrieveLayoutInformationFromCurrentView();
scaleCurrentViewPadding();
// TODO ignore this
//if (currentViewIsScalable()) {
scaleCurrentViewItself();
//}
if (currentViewHasScalableMargins()) {
scaleCurrentViewMargins();
}
if (currentViewExtendsView()) {
scaleCurrentViewMainParameter();
}
if (currentViewHasChildren()) {
scaleChildren();
}
}
private void retrieveCurrentViewFrom(final View V) {
currentView = V;
}
private void retrieveLayoutInformationFromCurrentView() {
currentViewLayoutParameters = currentView.getLayoutParams();
}
private void scaleCurrentViewPadding() {
final int LEFT = (int) (currentView.getPaddingLeft() * scale);
final int TOP = (int) (currentView.getPaddingTop() * scale);
final int RIGHT = (int) (currentView.getPaddingRight() * scale);
final int BOTTOM = (int) (currentView.getPaddingBottom() * scale);
currentView.setPadding(LEFT, TOP, RIGHT, BOTTOM);
}
// TODO ignore this
/*private boolean currentViewIsScalable() {
return !(currentView instanceof LineSeparator);
}*/
private void scaleCurrentViewItself() {
if (currentViewWidthIsNotDefinedBySpecialValue()) {
currentViewLayoutParameters.width *= scale;
}
if (currentViewHeightIsNotDefinedBySpecialValue()) {
currentViewLayoutParameters.height *= scale;
}
}
private boolean currentViewHasScalableMargins() {
boolean b = /* // TODO ignore this
currentView instanceof SeekBarTextView;
b |= currentView instanceof SegmentOfSeekBarScale;
b = !b;
b &=*/ currentViewLayoutParameters instanceof MarginLayoutParams;
return b;
}
private void scaleCurrentViewMargins() {
final MarginLayoutParams MLP = (MarginLayoutParams) currentViewLayoutParameters;
MLP.leftMargin *= scale;
MLP.rightMargin *= scale;
MLP.topMargin *= scale;
MLP.bottomMargin *= scale;
}
private boolean currentViewExtendsView() {
boolean b = currentViewIsATextView();
b |= currentViewIsASeekBar();
b |= currentViewIsACompoundButton();
return b;
}
private boolean currentViewIsATextView() {
return currentView instanceof TextView;
}
private boolean currentViewIsASeekBar() {
return currentView instanceof SeekBar;
}
private boolean currentViewIsACompoundButton() {
return currentView instanceof CompoundButton;
}
private void scaleCurrentViewMainParameter() {
if (currentViewIsATextView()) {
scaleTextSize();
}
if (currentViewIsASeekBar()) {
scaleSeekBarThumb();
}
if (currentViewIsACompoundButton()) {
scaleCompoundButton();
}
}
private void scaleTextSize() {
final TextView TV = (TextView) currentView;
final float OLD_SIZE = TV.getTextSize();
final float NEW_SIZE = OLD_SIZE * scale;
final int DIMENSION_UNIT = COMPLEX_UNIT_PX;
TV.setTextSize(DIMENSION_UNIT, NEW_SIZE);
}
private void scaleSeekBarThumb() {
retrieveThumbResourceId();
//TODO ignore this
// scaleThumb();
}
private void retrieveThumbResourceId() {
//TODO ignore this
//originalDrawableResourceId = R.drawable.seek_bar_thumb;
}
private void scaleThumb() {
final Drawable D = getScaledDrawableFromItsResourceId();
final SeekBar SB = (SeekBar) currentView;
SB.setThumb(D);
}
private Drawable getScaledDrawableFromItsResourceId() {
final Resources R = requester.getResources();
final Drawable D = R.getDrawable(originalDrawableResourceId);
final BitmapDrawable BD = (BitmapDrawable) D;
final Bitmap SOURCE = BD.getBitmap();
final int W = (int) (SOURCE.getWidth() * scale);
final int H = (int) (SOURCE.getHeight() * scale);
final boolean FILTER = false;
final Bitmap B = createScaledBitmap(SOURCE, W, H, FILTER);
return new BitmapDrawable(R, B);
}
private void scaleCompoundButton() {
prepareCompoundButtonButtonDrawableForScaling();
scaleCompoundButtonButtonDrawable();
}
private void prepareCompoundButtonButtonDrawableForScaling() {
final Bundle B;
//TODO ignore this
/*if (currentViewIsARadioButton()) {
B = getOriginalDrawablesResourceIdsForRadioButtonScaling();
} else {
B = getOriginalDrawablesResourceIdsForCheckBoxScaling();
}
originalDrawablesResourceIds = B;*/
}
private boolean currentViewIsARadioButton() {
return currentView instanceof RadioButton;
}
private Bundle getOriginalDrawablesResourceIdsForRadioButtonScaling() {
final Bundle B = new Bundle();
// TODO ignore this
/*final String CHECKED_STATE_KEY = "Drawable resource id for checked state";
final String UNCHECKED_STATE_KEY = "Drawable resource id for unchecked state";
final int CHECKED_STATE_VALUE = R.drawable.radio_checked_image;
final int UNCHECKED_STATE_VALUE = R.drawable.radio_unchecked_image;
B.putInt(CHECKED_STATE_KEY, CHECKED_STATE_VALUE);
B.putInt(UNCHECKED_STATE_KEY, UNCHECKED_STATE_VALUE);*/
return B;
}
private Bundle getOriginalDrawablesResourceIdsForCheckBoxScaling() {
final Bundle B = new Bundle();
// TODO ignore this
/*
final String CHECKED_STATE_KEY = "Drawable resource id for checked state";
final String UNCHECKED_STATE_KEY = "Drawable resource id for unchecked state";
final int CHECKED_STATE_VALUE = R.drawable.list_item_checked_image;
final int UNCHECKED_STATE_VALUE = R.drawable.list_item_unchecked_image;
B.putInt(CHECKED_STATE_KEY, CHECKED_STATE_VALUE);
B.putInt(UNCHECKED_STATE_KEY, UNCHECKED_STATE_VALUE);*/
return B;
}
private void scaleCompoundButtonButtonDrawable() {
final Drawable D = getScaledButtonDrawableFromOriginalDrawablesResourceIds();
final CompoundButton CB = (CompoundButton) currentView;
CB.setButtonDrawable(D);
}
private Drawable getScaledButtonDrawableFromOriginalDrawablesResourceIds() {
final Drawable CHECKED_STATE_DRAWABLE = getDrawableForCheckedState();
final Drawable UNCHECKED_STATE_DRAWABLE = getDrawableForUncheckedState();
final StateListDrawable SLD = new StateListDrawable();
final int[] CHECKED_STATE_SET = {state_checked};
SLD.addState(CHECKED_STATE_SET, CHECKED_STATE_DRAWABLE);
SLD.addState(WILD_CARD, UNCHECKED_STATE_DRAWABLE);
return SLD;
}
private Drawable getDrawableForCheckedState() {
retrieveOriginalDrawableResourceIdForCheckedState();
return getScaledDrawableFromItsResourceId();
}
private void retrieveOriginalDrawableResourceIdForCheckedState() {
final String KEY = "Drawable resource id for checked state";
final Bundle B = originalDrawablesResourceIds;
originalDrawableResourceId = B.getInt(KEY);
}
private Drawable getDrawableForUncheckedState() {
retrieveOriginalDrawableResourceIdForUncheckedState();
return getScaledDrawableFromItsResourceId();
}
private void retrieveOriginalDrawableResourceIdForUncheckedState() {
final String KEY = "Drawable resource id for unchecked state";
final Bundle B = originalDrawablesResourceIds;
originalDrawableResourceId = B.getInt(KEY);
}
private boolean currentViewHasChildren() {
return currentView instanceof ViewGroup;
}
private void scaleChildren() {
final ViewGroup VG = (ViewGroup) currentView;
final int SIZE = VG.getChildCount();
for (int i = 0; i < SIZE; ++i) {
scale(VG.getChildAt(i));
}
}
public void scaleChildrenOf(final ViewGroup VG) {
final int SIZE = VG.getChildCount();
for (int i = 0; i < SIZE; ++i) {
scale(VG.getChildAt(i));
}
}
public void scale(final ListView LV) {
//TODO
/* ignore this
final int DIVIDER_OLD_HEIGHT = LV.getDividerHeight();
final int DIVIDER_NEW_HEIGHT = (int) (DIVIDER_OLD_HEIGHT * scale);
LV.setDividerHeight(DIVIDER_NEW_HEIGHT);
Toast.makeText(requester, "Height: " + DIVIDER_OLD_HEIGHT, Toast.LENGTH_SHORT).show();*/
final int SIZE = LV.getCount();
for (int i = 0; i < SIZE; ++i) {
scale(LV.getAdapter().getView(i,LV.getChildAt(i),LV));
}
//TODO
}
}
我在两个模拟器上测试了这个代码,这是我在Genymotion中创建的。
第一个仿真器^具有以下参数:
- 400 x 800像素;
- ldpi(120dpi);
第二个^^有一个以下参数:
800 x 1280像素;
xxhdpi(480dpi)。
^所有ListView项目在该模拟器上正确显示。因为我为该模拟器手动调整了我的xml文件。
^^只有部分ListView项目在该模拟器上正确显示(缩放)。
我建议你创建我上面提到的模拟器。它有助于查看我正在寻找解决问题的深度。
我试图评论可能产生错误的所有代码行。但是,如果我的代码仍然产生错误,请告诉我代码行。我会纠正他们。
我一直在寻找解决方案两天。
listView.getChildAt();
listView.setSelection();
listView.getSelectedView();
listView.getFocusedChild();
<!-- and other methods similar to them -->
所有这些都没有帮助解决问题。其中一些产生异常(如NullPointerException)。他们中的一些人什么都不做 我试图覆盖SimpleAdapter的getView()方法并使用LayoutInflater.inflate()。但那也行不通。它导致了NullPointerException 也许我做错了什么?
任何帮助将不胜感激。
我需要一个工作方法“public void scale(final ListView LV)”,它将扩展所有ListView项目。
修改
感谢Jim,我发现要扩展所有ListView项目,您需要:
1)覆盖getView()方法;
2)在该方法中使用这些代码行(或类似代码):
if(convertView==null) {
// inflate the layout
LayoutInflater inflater = ((Activity) mContext).getLayoutInflater();
convertView = inflater.inflate(layoutResourceId, parent, false);
pageScaler.scale(convertView);
}
如果您尝试使用这些代码行(或类似代码)
if(convertView==null) {
// This a new view we inflate the new layout
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(layoutResourceId, null);
pageScaler.scale(convertView);
}
您将获得NullPointerException(当您尝试扩展convertView时)。至少在我的情况下发生了这种情况。
答案 0 :(得分:0)
不幸的是,您的方法不正确。您不应构建ListView,然后缩放图像。您应该使用自定义ArrayAdapter并在将每个项目传递到ListView时对其进行缩放。
例如:
http://www.javacodegeeks.com/2013/06/android-listview-custom-adapter-with-imageview.html
或在这里:
http://www.javacodegeeks.com/2013/09/android-listview-with-adapter-example.html