AndroidTVWidget框架之運動焦點框(五)

AndroidTVWidget框架
在此框架上封裝了幾個類用于快速實現(xiàn)焦點動畫。

使用AndroidTVWidget完成運動焦點框效果。

  • 盡可能減少布局層級。
  • 需獲取焦點的view最好在同一層級上。
  • 焦點框要處于最上層,避免遮蓋。
  • 注意view的邊距,防止view放大時顯示不全。

以下展示幾種不同布局環(huán)境下對焦點框的處理:重點是獲取到view的焦點并對焦點得失兩種狀態(tài)分別處理。

Demo地址
在布局中添加MainUpView,使MainUpView處于布局的上層。

設(shè)置焦點框:

private void initMoveBridge() {
    float density = getResources().getDisplayMetrics().density;
    mEffectNoDrawBridge = new EffectNoDrawBridge();
    mainUpView.setEffectBridge(mEffectNoDrawBridge);
    mEffectNoDrawBridge.setUpRectResource(R.drawable.white_light); // 設(shè)置移動邊框圖片.
    RectF rectF = new RectF(15 * density, 15 * density, 14 * density, 15 * density);
    mEffectNoDrawBridge.setDrawUpRectPadding(rectF);
}

對view添加監(jiān)聽:

  private void initListener(){
    cardView1.setOnFocusChangeListener(this);
    cardView2.setOnFocusChangeListener(this);
    cardView3.setOnFocusChangeListener(this);
    cardView4.setOnFocusChangeListener(this);
    cardView5.setOnFocusChangeListener(this);
    cardView6.setOnFocusChangeListener(this);
    cardView7.setOnFocusChangeListener(this);
    cardView8.setOnFocusChangeListener(this);
    cardView9.setOnFocusChangeListener(this);
}

處理:

    @Override
public void onFocusChange(View v, boolean hasFocus) {
    if (hasFocus) {
        mOldView = v;
        mEffectNoDrawBridge.setVisibleWidget(false);
        //可以對某個view進行特殊處理
//            if (v.getId()==R.id.card_img) {
//                mEffectNoDrawBridge.setFocusView(v, 1.05f);
//            } else {
//                mEffectNoDrawBridge.setFocusView(v, 1.15f);
//            }
        mEffectNoDrawBridge.setFocusView(v, 1.15f);
        v.bringToFront();
    } else {
        mEffectNoDrawBridge.setUnFocusView(mOldView);
        mEffectNoDrawBridge.setVisibleWidget(true);
    }
}

詳情見Demo中的MainActivity

另一種方式:

  private void initFocusTree(){
    rootView.getViewTreeObserver().addOnGlobalFocusChangeListener(new ViewTreeObserver.OnGlobalFocusChangeListener() {
        @Override
        public void onGlobalFocusChanged(View oldFocus, View newFocus) {

            if (newFocus != null ) {
                //可以在此對newFocus進行過濾,可以使一些view不能獲取焦點或者展示不同的樣式。
                mEffectNoDrawBridge.setVisibleWidget(false);
                mNewFocus = newFocus;
                mOldView = oldFocus;
                mainUpView.setFocusView(newFocus, oldFocus, 1.2f);
                newFocus.bringToFront();
            } else { // 標題欄處理.
                mNewFocus = null;
                mOldView = null;
                mainUpView.setUnFocusView(oldFocus);
                mEffectNoDrawBridge.setVisibleWidget(true);
            }
        }
    });
}

不同應(yīng)用場景中的封裝類:

MainUpViewActivity

  • 適合含有View,不包含ViewGroup的布局。
  • 使用簡單方便。
  • 創(chuàng)建Activity繼承MainUpViewActivity
  • 在onCreate方法中調(diào)用init方法初始化
  • 不需要在布局中添加MainUpView控件

如下:

public class Example1Activity extends MainUpViewActivity {
    @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.activity_main);
        //參數(shù)分別為邊框圖片,左上右下的邊距,根據(jù)需求自行調(diào)整
         init(R.drawable.white_light,12,12,12,12);
     }
}

若要使一些view不能獲取焦點或者展示不同的樣式??芍貙慽nitFocusTree();
詳情見Demo中的Example1Activity。

BaseActivity
用于處理activity中RecyclerViewTV的焦點框,RecyclerViewTV是AndroidTVWidget中為Android TV開發(fā)自定義的控件,使用RecyclerViewTV代替RecyclerView。 BaseActivity是一個抽象類,只需實現(xiàn)幾個固定的方法即可。

public class Example2Activity extends BaseActivity {

@Override
public int getLayout() {
    //布局xml
    return 0;
}

@Override
public void initView() {
    init(...);//初始化焦點框
    //初始化布局
}

@Override
public void loadData() {
    //數(shù)據(jù)加載
}

@Override
public RecyclerView.LayoutManager getLayoutManager() {
    //RecyclerView的LayoutManager類型
    return null;
}

@Override
public RecyclerView.Adapter getAdapter() {
    //適配器
    return null;
}

@Override
public void onItemClick(View itemView, int position) {
    //item的點擊事件
}

@Override
public void onItemSelected(View itemView, int position) {
    //選中item
}

@Override
public void onItemUnSelected(View itemView, int position) {
    //失去選中item
}
}

setAutoFocus(false);//默認為true,第一項獲取焦點;為false,不自動獲取焦點。
setAnimScale(1.2f);//設(shè)置焦點放大的倍數(shù),默認為1.2倍。

當前BaseActivity實現(xiàn)類中的其他view,可以通過setOnFocusListener()來監(jiān)聽焦點并實現(xiàn)動畫。詳情請見,Demo中的Example2Activity。

BaseFragment
RecyclerViewTV在Fragment中,與BaseActivity類似。
見Demo中Example3Fragment。

public class Example3Fragment extends BaseFragment {

private RecyclerViewTV recyclerViewTV;
private MainUpView mainUpView;
private List<String> list=new ArrayList<>();
private ExamAdapter examAdapter;

@Override
public int getLayout() {
    return 0;
}

@Override
public void initView(View view) {
    
}

@Override
public void loadData() {
   
}

@Override
public void onItemClick(View itemView, int position) {

}

@Override
public void onItemSelected(View itemView, int position) {

}

@Override
public void unItemSelected(View itemView, int position) {

}

@Override
public RecyclerView.Adapter getAdapter() {
    return null;
}

@Override
public RecyclerView.LayoutManager getLayoutManager() {
    
    return null;
}
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容