1. 程式人生 > >android屏幕適配方案

android屏幕適配方案

得到 glob src count span imageview ica height void

曾經看了android的屏幕適配方案,有非常多種。當中自己用到的一種是:先找一款主流的分辨率的android機,如:1080*1920的分辨率做基準,然後在這個基準上。調整好一切布局。圖片。適配其它手機分辨率的手機。用百分比來調節。比如:在480*800的主流手機上,寫了一個height=520,那麽在480*800的手機上,這個控件的高度則為

480height = 520 * 屏幕高度/1920. 這種方案做屏幕適配。


項目遇到一個問題。

在剩余空間裏。在1080*1920的手機上適配非常好,可是在480*800的低分辨率手機上則顯示不完整。

查看了原因:由於我的圖片資源是240*240的。

布局的ImageView的寬高是自適應的。

所以會導致圖片太大。而其余的字體,圖片就不能全然顯示。所以解決方式有2種:一是做低分辨率的資源圖。二是外層嵌套scrollView控件,讓其滑動顯示剩余不能全然的部分。


動態布局首先要得到xml控件的寬高:

前幾天。在自己定義控件的時候碰到個問題。就是在怎樣獲取自己定義控件的高寬。在自己定義控件類的構造函數中,本來以為能夠輕松獲取。但事實不是這樣。

我測試了以下代碼:
先是布局代碼:
<com.lml.getvalues.MyView
android:id="@+id/myView"
android:layout_width="match_parent"


android:layout_height="150px"
android:background="#ff0000" />
再是MyView的構造函數的代碼:
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
a="在MyView構造函數中 : MeasuredWidth:"+this.getMeasuredWidth()+";"+"MeasuredHeight:"+this.getMeasuredHeight()+";"

+"Width:"+this.getWidth()+";"+"Height:"+this.getHeight()+"\n";
String h="",w="";
for(int i =0 ;i < attrs.getAttributeCount();i++){
if("layout_height".equals(attrs.getAttributeName(i))){
h=attrs.getAttributeValue(i);
}else if("layout_width".equals(attrs.getAttributeName(i))){
w=attrs.getAttributeValue(i);
}
}
b="在構造函數attrs中 : width:"+w+";"+"height:"+h+"\n";

}

編譯得到a="在MyView構造函數中 : MeasuredWidth:0;MeasuredHeight:0;Width:0;Height:0".
b="在構造函數attrs中 : width:-1;height:150.0px

結果顯示當width為match_parent等數值時。僅僅顯示-1等。不能滿足我的需求。



然後我試著在對應Activity的onCreate中獲取高寬。獲得的所有是0.但我在onCreate中的加了個點擊控件獲取高寬事件,能正確獲取高寬。

我在網上查了下資料,由於在onCreate中控件還未被度量,所以獲取肯定為0.網上有獲取三個方法,方法例如以下:
方法一,在onCreate中加入例如以下代碼:
int w = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
int h = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
myView.measure(w, h);
int height = myView.getMeasuredHeight();
int width = myView.getMeasuredWidth();
tvValues.append("方法一: height:"+height + ",width:" + width+"\n");

方法二能夠實現,代碼例如以下:
ViewTreeObserver vto2 = myView.getViewTreeObserver();
vto2.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
myView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
tvValues.append( "方法二: height:"+myView.getHeight() + ",width:" + myView.getWidth()+"\n");
}
});
但我發現removeGlobalOnLayoutListener在API 級別 16 開始已經廢棄,假設去掉。系統會讀取多次。

再來看看方法三。代碼例如以下:

ViewTreeObserver vto = myView.getViewTreeObserver();
vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
public boolean onPreDraw() {
myView.getViewTreeObserver().removeOnPreDrawListener(this);
int height = myView.getMeasuredHeight();
int width = myView.getMeasuredWidth();
tvValues.append("方法三: height:"+height + ",width:" + width + "..\n");
return true;
}
});
我在網上資料的基礎上加入了myView.getViewTreeObserver().removeOnPreDrawListener(this);這一條,這個能夠保證系統執行一次。

_____________________________________________________________________________________________________________


出現的問題:(1)用上面的2個回調監聽函數。監聽函數會一直調用,關閉不了。並且屏幕跳轉會出現閃屏的現象。所以放棄了

public void setActionBar(){
    ViewTreeObserver  observer = mScrollView.getViewTreeObserver();
//    observer.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
//      @Override
//      public boolean onPreDraw() {
//        int i = 0;
//        Log.e("HomeFragment:" + (i++));
//        //int scrollHeight = mScrollView.getChildAt(0).getHeight();
//        int scrollHeight = getScreenHeight() - getActionView().getHeight() - mHomeAd.getHeight() - mMineCare.getHeight() -MainUI.bottomHeight;
//        int TextHeight = mHomeProgramTxt.getHeight();
//
//        if(scrollHeight > (bitmapHeight+TextHeight)*2){
//          //大屏幕
//          int firstBarHeight = mFirstBar.getHeight();
//          int blankHeight = scrollHeight - firstBarHeight*2;
//
//          LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) mFirstBar.getLayoutParams();
//          params.setMargins(0, blankHeight / 3, 0, 0);
//          mFirstBar.setLayoutParams(params);
//
//          LinearLayout.LayoutParams secondParams = (LinearLayout.LayoutParams) mSecondBar.getLayoutParams();
//          secondParams.setMargins(0,blankHeight/3,0,0);
//          mSecondBar.setLayoutParams(secondParams);
//        }
//        mScrollView.getViewTreeObserver().removeOnPreDrawListener(this);
//        return true;
//      }
//    });

(2) 選擇使用第一種方法。假設xml裏面是用的wrap_content寬高的,能夠用getMeasureHeight()方法獲取到控件的值,可是動態設置的值僅僅有自己記住這個值大小

 public void set(){
    int w = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
    int h = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);

    getActionView().measure(w, h);
    mMineCare.measure(w,h);
    //詳細值單獨賦值
    int homeAdHeight = 520 * getScreenHeight() / 1920;
    int scrollHeight = getScreenHeight() - getActionView().getMeasuredHeight() - homeAdHeight - mMineCare.getMeasuredHeight() -MainUI.bottomHeight;
    mHomeProgramTxt.measure(w,h);
    int TextHeight = mHomeProgramTxt.getMeasuredHeight();

    if(scrollHeight > (bitmapHeight+TextHeight)*2.5){
      //大屏幕
      mFirstBar.measure(w,h);
      int firstBarHeight = mFirstBar.getMeasuredHeight();
      int blankHeight = scrollHeight - firstBarHeight*2;

      LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) mFirstBar.getLayoutParams();
      params.setMargins(0, blankHeight / 3, 0, 0);
      mFirstBar.setLayoutParams(params);
      mSecondBar.setLayoutParams(params);
    }
  }


實現低分辨率適配效果:

技術分享


高分辨率效果:

技術分享

android屏幕適配方案