當前位置:首頁 » 安卓系統 » android刷新按鈕

android刷新按鈕

發布時間: 2025-02-06 11:57:17

㈠ 如何強制刷新Android系統圖庫

系統自帶的話,一般都是往下拉。如果沒有,那就是不能刷新
不過我們可以投機取巧啊!你點一下設置→應用→找到圖庫(在全部應用里),強制關閉
之後你再打開就好了,系統崩潰就重啟。或直接重啟也行

㈡ Android 怎麼實現支持所有View的通用的下拉刷新控制項

下拉刷新對於一個app來說是必不可少的一個功能,在早期大多數使用的是chrisbanes的PullToRefresh,或是修改自該框架的其他庫。而到現在已經有了更多的選擇,github上還是有很多體驗不錯的下拉刷新。
而下拉刷新主要有兩種實現方式:
1. 在ListView中添加header和footer,監聽ListView的滑動事件,動態設置header/footer的高度,但是這種方式只適用於ListView,RecyclerView。
2. 第二種方式則是繼承ViewGroup或其子類,監聽事件,通過scroll或Layout的方式移動child。如圖(又分兩種情況)

Layout時將header放到屏幕外面,target則填充滿屏幕。這個也是SwipeRefreshLayout的實現原理(第二種,只下拉header)

這兩種(指的是繼承ListView或繼承ViewGroup)下拉刷新的實現方式主要有以下區別

繼承ListView/RecyclerView

繼承ViewGroup或其子類

適用范圍
ListView/Recycler
理論支持所有View和ViewGroup

載入更多
實現簡單,體驗好
可以實現,看需求了,做不出ListView那種載入效果的,體驗比較一般

多點觸控
可以完美支持
header下拉狀態中是完美支持的,但是回去之後,很難將多點觸控事件傳遞給child

案例
QQ好友列表
美團、京東等

而今天,我打算先講第二種方式實現方式,繼承ViewGroup,代碼可以直接參考SwipeRefreshLayout,或者pullToRefresh,或者ultra-pull-to-refresh

一、思考和需求

下拉刷新需要幾個狀態:Reset–> Pull – > Refreshing – >Completed –>Reset

為了應對各式各樣的下拉刷新設計,我們應該提供設置自定義的Header,開發者可以通過實現介面從而自定義自己的header。

而且header可以有兩種顯示方式,一種是只下拉header,另外一種則是header和target一起下拉。

二、著手實現代碼

2.1 定義Header的介面,創建自定義Layout

<code class="hljs java">/**
* Created by AItsuki on 2016/6/13.
*
*/
public enum State {
RESET, PULL, LOADING, COMPLETE
}</code>

<code class="hljs java">/**
* Created by AItsuki on 2016/6/13.
*
*/
public interface RefreshHeader {

/**
* 鬆手,頭部隱藏後會回調這個方法
*/
void reset();

/**
* 下拉出頭部的一瞬間調用
*/
void pull();

/**
* 正在刷新的時候調用
*/
void refreshing();

/**
* 頭部滾動的時候持續調用
* @param currentPos target當前偏移高度
* @param lastPos target上一次的偏移高度
* @param refreshPos 可以鬆手刷新的高度
* @param isTouch 手指是否按下狀態(通過scroll自動滾動時需要判斷)
* @param state 當前狀態
*/
void onPositionChange(float currentPos, float lastPos, float refreshPos, boolean isTouch, State state);

/**
* 刷新成功的時候調用
*/
void complete();
}</code>
package com.aitsuki.custompulltorefresh;

import android.content.Context;
import android.graphics.Color;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.widget.ImageView;

/**
* Created by AItsuki on 2016/6/13.
* -
*/
public class RefreshLayout extends ViewGroup {

private View refreshHeader;
private View target;
private int currentTargetOffsetTop; // target偏移距離
private boolean hasMeasureHeader; // 是否已經計算頭部高度
private int touchSlop;
private int headerHeight; // header高度
private int totalDragDistance; // 需要下拉這個距離才進入鬆手刷新狀態,默認和header高度一致

public RefreshLayout(Context context) {
this(context, null);
}

public RefreshLayout(Context context, AttributeSet attrs) {
super(context, attrs);

touchSlop = ViewConfiguration.get(context).getScaledTouchSlop();

// 添加默認的頭部,先簡單的用一個ImageView代替頭部
ImageView imageView = new ImageView(context);
imageView.setImageResource(R.drawable.one_piece);
imageView.setBackgroundColor(Color.BLACK);
setRefreshHeader(imageView);
}

/**
* 設置自定義header
*/
public void setRefreshHeader(View view) {
if (view != null && view != refreshHeader) {
removeView(refreshHeader);

// 為header添加默認的layoutParams
ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
if (layoutParams == null) {
layoutParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
view.setLayoutParams(layoutParams);
}
refreshHeader = view;
addView(refreshHeader);
}
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (target == null) {
ensureTarget();
}

if (target == null) {
return;
}

// ----- measure target -----
// target占滿整屏
target.measure(MeasureSpec.makeMeasureSpec(
getMeasuredWidth() - getPaddingLeft() - getPaddingRight(),
MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(
getMeasuredHeight() - getPaddingTop() - getPaddingBottom(), MeasureSpec.EXACTLY));

// ----- measure refreshView-----
measureChild(refreshHeader, widthMeasureSpec, heightMeasureSpec);
if (!hasMeasureHeader) { // 防止header重復測量
hasMeasureHeader = true;
headerHeight = refreshHeader.getMeasuredHeight(); // header高度
totalDragDistance = headerHeight; // 需要pull這個距離才進入鬆手刷新狀態
}
}

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
final int width = getMeasuredWidth();
final int height = getMeasuredHeight();
if (getChildCount() == 0) {
return;
}

if (target == null) {
ensureTarget();
}
if (target == null) {
return;
}

// onLayout執行的時候,要讓target和header加上偏移距離(初始0),因為有可能在滾動它們的時候,child請求重新布局,從而導致target和header瞬間回到原位。

// target鋪滿屏幕
final View child = target;
final int childLeft = getPaddingLeft();
final int childTop = getPaddingTop() + currentTargetOffsetTop;
final int childWidth = width - getPaddingLeft() - getPaddingRight();
final int childHeight = height - getPaddingTop() - getPaddingBottom();
child.layout(childLeft, childTop, childLeft + childWidth, childTop + childHeight);

// header放到target的上方,水平居中
int refreshViewWidth = refreshHeader.getMeasuredWidth();
refreshHeader.layout((width / 2 - refreshViewWidth / 2),
-headerHeight + currentTargetOffsetTop,
(width / 2 + refreshViewWidth / 2),
currentTargetOffsetTop);
}

/**
* 將第一個Child作為target
*/
private void ensureTarget() {
// Don't bother getting the parent height if the parent hasn't been laid
// out yet.
if (target == null) {
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
if (!child.equals(refreshHeader)) {
target = child;
break;
}
}
}
}
}</code>

㈢ android中怎麼實現上拉刷新

這篇文章主要介紹了android實現listview下拉刷新和上拉刷新效果,Android的ListView上拉下拉刷新,原理都一樣,在Touch事件中操作header/footer的paddingTop屬性,需要的朋友可以參考下

{

privatestaticfinalStringTAG=PullToLoadListView.class.getSimpleName();

privatestaticfinalintSTATE_NON=0;
privatestaticfinalintSTATE_PULL_TO_REFRESH=1;
privatestaticfinalintSTATE_RELEASE_TO_REFRESH=2;
privatestaticfinalintSTATE_REFRESHING=3;

privateintstate;

privateintfirstVisibleItem;
privateintlastVisisibleItem;

privatefloatprevY=0;

privateViewheaderView;
privateViewfooterView;

//headerwidgets
;
;
privateTextViewheaderText;
;
;
//footerwidgets
;
privateTextViewfooterText;

privatebooleanheaderIsHanding=false;
privatebooleanfooterIsHanding=false;

privateintheaderHeight;
privateintfooterHeight;

;

;

;

publicPullToLoadListView(Contextcontext){
super(context);
init(context);
}

publicPullToLoadListView(Contextcontext,AttributeSetattrs){
super(context,attrs);
init(context);
}

privatevoidinit(Contextcontext){
state=STATE_NON;
firstVisibleItem=0;
lastVisisibleItem=0;

LayoutInflaterinflater=LayoutInflater.from(context);
headerView=inflater.inflate(R.layout.view_pull_header,null);
footerView=inflater.inflate(R.layout.view_pull_footer,null);

headerProgressBar=(ProgressBar)headerView.findViewById(R.id.progressbar);
headerImageArrow=(ImageView)headerView.findViewById(R.id.arrow);
headerText=(TextView)headerView.findViewById(R.id.text);
headerArrowAnim=newRotateAnimation(0,-180,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
headerArrowAnim.setDuration(300);
headerArrowAnim.setFillAfter(true);
headerArrowReverseAnim=newRotateAnimation(-180,0,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
headerArrowReverseAnim.setDuration(300);
headerArrowReverseAnim.setFillAfter(true);

footerProgressBar=(ProgressBar)footerView.findViewById(R.id.progressbar);
footerText=(TextView)footerView.findViewById(R.id.text);

measureView(headerView);
measureView(footerView);
headerHeight=headerView.getMeasuredHeight();
footerHeight=footerView.getMeasuredHeight();
headerView.setPadding(0,-1*headerView.getMeasuredHeight(),0,0);
footerView.setPadding(0,-1*footerView.getMeasuredHeight(),0,0);
headerView.invalidate();
footerView.invalidate();
addHeaderView(headerView,null,false);
addFooterView(footerView,null,false);

super.setOnScrollListener(this);
}

privatevoidmeasureView(Viewview){
ViewGroup.LayoutParamslp=view.getLayoutParams();
if(lp==null){
lp=newViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.WRAP_CONTENT);
}
intchildWidthSpec=ViewGroup.getChildMeasureSpec(0,0,lp.width);
intchildHeightSpec;
if(lp.height>0){
childHeightSpec=MeasureSpec.makeMeasureSpec(0,MeasureSpec.EXACTLY);
}else{
childHeightSpec=MeasureSpec.makeMeasureSpec(0,MeasureSpec.UNSPECIFIED);
}
view.measure(childWidthSpec,childHeightSpec);
}

privatevoidresetHeader(){
//headerView.setPadding(0,-1*headerHeight,0,0);
resetAnim=newResetAnimation(headerView,headerHeight,headerView.getPaddingTop());
resetAnim.start();
}

privatevoidresetFooter(){
resetAnim=newResetAnimation(footerView,footerHeight,footerView.getPaddingTop());
resetAnim.start();
}

(intstate){
if(this.state==state){
return;
}
intprevState=this.state;
this.state=state;

switch(state){
caseSTATE_NON:
headerProgressBar.setVisibility(View.INVISIBLE);
headerImageArrow.setVisibility(View.VISIBLE);
headerImageArrow.clearAnimation();
headerText.setText("PullDownToRefresh");
break;
caseSTATE_PULL_TO_REFRESH:
headerProgressBar.setVisibility(View.INVISIBLE);
headerImageArrow.setVisibility(View.VISIBLE);
headerText.setText("PullDownToRefresh");
if(prevState==STATE_RELEASE_TO_REFRESH){
headerImageArrow.startAnimation(headerArrowReverseAnim);
}else{
headerImageArrow.clearAnimation();
}
break;
caseSTATE_RELEASE_TO_REFRESH:
headerProgressBar.setVisibility(View.INVISIBLE);
headerImageArrow.setVisibility(View.VISIBLE);
headerImageArrow.startAnimation(headerArrowAnim);
headerText.setText("ReleaseToRefresh");
break;
caseSTATE_REFRESHING:
headerProgressBar.setVisibility(View.VISIBLE);
headerImageArrow.setVisibility(View.INVISIBLE);
headerImageArrow.clearAnimation();
headerText.setText("Refreshing");
break;
default:
break;
}
}

(intstate){
if(this.state==state){
return;
}
this.state=state;

switch(state){
caseSTATE_NON:
footerProgressBar.setVisibility(View.INVISIBLE);
footerText.setText("PullUpToRefresh");
break;
caseSTATE_PULL_TO_REFRESH:
footerProgressBar.setVisibility(View.INVISIBLE);
footerText.setText("PullUpToRefresh");
break;
caseSTATE_RELEASE_TO_REFRESH:
footerProgressBar.setVisibility(View.INVISIBLE);
footerText.setText("ReleaseToRefresh");
break;
caseSTATE_REFRESHING:
footerProgressBar.setVisibility(View.VISIBLE);
footerText.setText("Refreshing");
break;
default:
break;
}
}

@Override
publicvoidsetOnScrollListener(OnScrollListenerl){
this.onScrollListener=l;
}

(){
this.onLoadingListener=onLoadingListener;
}

publicvoidloadCompleted(){
if(headerIsHanding){
changeHeaderViewByState(STATE_NON);
resetHeader();
headerIsHanding=false;
}
if(footerIsHanding){
changeFooterViewByState(STATE_NON);
resetFooter();
footerIsHanding=false;
}
}

(MotionEventev){
headerIsHanding=true;
floattempY=ev.getRawY();
floatvector=tempY-prevY;
vector/=2;
prevY=tempY;
if(vector>0){
intnewPadding=(int)(headerView.getPaddingTop()+vector);
newPadding=Math.min(newPadding,headerHeight/2);
headerView.setPadding(0,newPadding,0,0);
if(state!=STATE_REFRESHING){
if(newPadding>0){
changeHeaderViewByState(STATE_RELEASE_TO_REFRESH);
}else{
changeHeaderViewByState(STATE_PULL_TO_REFRESH);
}
}
}else{
if(state==STATE_RELEASE_TO_REFRESH||state==STATE_PULL_TO_REFRESH){
intnewPadding=(int)(headerView.getPaddingTop()+vector);
newPadding=Math.max(newPadding,-1*headerHeight);
headerView.setPadding(0,newPadding,0,0);
if(newPadding<=-1*headerHeight){
changeHeaderViewByState(STATE_NON);
headerIsHanding=false;
}elseif(newPadding<=0){
changeHeaderViewByState(STATE_PULL_TO_REFRESH);
}else{

}
}
}
}

(MotionEventev){
footerIsHanding=true;
floattempY=ev.getRawY();
floatvector=tempY-prevY;
vector/=2;
prevY=tempY;
if(vector<0){
intnewPadding=(int)(footerView.getPaddingTop()-vector);
if(newPadding>0){
newPadding=0;
}
footerView.setPadding(0,newPadding,0,0);
if(state!=STATE_REFRESHING){
if(newPadding<0){
changeFooterViewByState(STATE_PULL_TO_REFRESH);
}else{
changeFooterViewByState(STATE_RELEASE_TO_REFRESH);
}
}
}else{
intnewPadding=(int)(footerView.getPaddingTop()-vector);
newPadding=Math.min(newPadding,footerHeight);
footerView.setPadding(0,newPadding,0,0);
if(newPadding<=-1*footerHeight){
changeFooterViewByState(STATE_NON);
footerIsHanding=false;
}elseif(newPadding<0){
changeFooterViewByState(STATE_PULL_TO_REFRESH);
}
}
}

㈣ Android屏幕刷新機制—VSync、Choreographer 全面理解!

在閱讀本篇之前,建議先了解《View的工作原理》、《Handler:Android消息機制》、《Window和WindowManager》、《Activity的啟動過程詳解》等基礎知識。接下來,我們深入探討Android屏幕刷新機制,特別是VSync、Choreographer的重要作用。

屏幕刷新機制的背景和疑問:在Android中,我們追求高效的布局優化和減少主線程耗時操作,以避免出現丟幀現象。丟幀嚴重時,界面會表現出明顯的卡頓感。我們知道,手機通常以每秒60次的頻率刷新屏幕,即每16.6毫秒刷新一次。然而,實際操作中,我們經常面臨如何在固定刷新頻率與CPU/GPU計算速度不匹配的情況下的挑戰。

屏幕撕裂問題:CPU/GPU在計算和刷新屏幕時,可能因為數據刷新的速度跟不上屏幕刷新的速度,導致屏幕上顯示的數據不完整,這就是屏幕撕裂。雙緩存機制可以有效解決這一問題,通過使用兩個緩沖區,確保屏幕在刷新時得到的數據是完整的。VSync(垂直同步)是實現雙緩存交換的關鍵,它利用屏幕刷新間隙進行緩沖區的交換,確保了屏幕顯示的連續性和完整性。

Android屏幕刷新機制詳解:在Android4.1之前,系統通過雙緩存+VSync機制來管理屏幕刷新。然而,隨著系統的發展,針對更復雜的界面和計算需求,Android4.1引入了Project Butter計劃,優化了顯示性能,使得CPU和GPU在VSync信號到來時開始下一幀的渲染,有效減少了卡頓現象。為了進一步提升性能,Android引入了三緩存機制,通過增加額外的緩沖區,最大限度地利用等待VSync的時間,但同時也帶來了額外的內存開銷。

Choreographer的作用:Choreographer作為關鍵的系統組件,負責協調UI的繪制流程,確保在VSync信號到來時啟動下一幀的渲染。通過使用Choreographer,系統可以更高效地管理UI任務的執行順序,優化顯示性能。Choreographer通過創建特定的線程實例,安排和處理UI相關的回調任務,包括繪制任務(TRAVERSAL)、動畫任務(ANIMATION)等,確保在合適的時機執行這些任務,從而達到流暢的用戶體驗。

非同步消息與同步屏障:在處理UI任務時,Choreographer使用非同步消息來調度任務執行,而同步屏障則是用於控制消息隊列的執行順序,確保在特定任務完成後才執行後續任務。這些機制協同工作,使得Choreographer能夠高效地管理系統資源,優化顯示性能。

總結:理解Android屏幕刷新機制和Choreographer的作用對於優化UI性能、減少卡頓現象至關重要。通過合理利用雙緩存、VSync、Choreographer等技術,可以顯著提升Android應用的用戶體驗。深入學習這些機制的基礎知識,並將其應用於實際開發中,將有助於開發者構建更加流暢和響應迅速的Android應用。

㈤ 如何定時刷新Android界面

Android程序中可以使用的界面刷新方法有兩種,分別是利用Handler和利用postInvalidate()來實現在線程中刷新界面。
利用Handler刷新界面
實例化一個Handler對象,並重寫handleMessage方法調用invalidate()實現界面刷新;而在線程中通過sendMessage發送界面更新消息。
復制到剪貼板 java代碼// 在onCreate()中開啟線程 new Thread(new GameThread()).start();、 // 實例化一個handler Handler myHandler = new Handler() { //接收到消息後處理 public void handleMessage(Message msg) { switch (msg.what) { case Activity01.REFRESH: mGameView.invalidate(); //刷新界面 break; } super.handleMessage(msg); } }; class GameThread implements Runnable { public void run() { while (!Thread.currentThread().isInterrupted()) { Message message = new Message(); message.what = Activity01.REFRESH; //發送消息 Activity01.this.myHandler.sendMessage(message); try { Thread.sleep(100); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } } } 使用postInvalidate()刷新界面
使用postInvalidate則比較簡單,不需要handler,直接在線程中調用postInvalidate即可。
復制到剪貼板 Java代碼class GameThread implements Runnable { public void run() { while (!Thread.currentThread().isInterrupted()) { try { Thread.sleep(100); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } //使用postInvalidate可以直接在線程中更新界 mGameView.postInvalidate(); } } }

㈥ Android下拉刷新,上拉載入,有沒有比較好的第三方庫

拉刷新和下拉刷新的兩種方法(包括使用第三方庫MJRefresh)一、使用蘋果原生的方法1、下拉刷新2、上拉刷新(1首先要新建一個footer得XIB文件,當然同時包括對應的控制器文件,例如在XIB文件中可以如下拖拉對應的控制項(2然後在代碼文件中寫一個實例方法+(instancetype)footer{return[[[NSBundlemainBundle]loadNibNamed:@"XIB文件名"owner:niloptions:nil]lastObject];}(3然後在我們的列表控制器中調用:/***集成上拉刷新控制項*/-(void)refreshUpStateDateList{XBLoadMoreFooter*footer=[XBLoadMoreFooterfooter];footer.hidden=YES;//一開始是要隱藏起來的,當scrollView拖拉到底部的時候我們才把它放出來self.tableView.tableFooterView=footer;//其實就是相當於把這個XIB文件當作是tableView的Footer}(4上拉到底部的時候去調用刷新數據的方法二、使用第三方庫MJRefresh1、下拉刷新遵守協議:,然後其實就是把它當成tableview的header來用2、下拉刷新3、需要注意:最後需要dealloc

熱點內容
均線差演算法 發布:2025-02-06 15:13:22 瀏覽:459
androidbrowser 發布:2025-02-06 15:09:49 瀏覽:622
勇敢的心ftp 發布:2025-02-06 15:09:03 瀏覽:327
php日誌分析 發布:2025-02-06 15:08:19 瀏覽:874
36腳本大廳作者 發布:2025-02-06 14:55:53 瀏覽:408
買電腦配送伺服器嗎 發布:2025-02-06 14:54:58 瀏覽:243
伺服器怎麼刪除資源 發布:2025-02-06 14:36:14 瀏覽:672
安卓如何設置桌面返回鍵 發布:2025-02-06 13:58:15 瀏覽:49
bi可視化php 發布:2025-02-06 13:50:15 瀏覽:932
shell寫腳本文件 發布:2025-02-06 13:47:32 瀏覽:231