最近做了个推荐影片的APP,根据标签展示不同的视频列表,用遥控器上下左右按键来操作标签。当标签数目较少,能一屏展示时的代码如下:
acivity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/bg_apps_now_holo"
android:orientation="vertical"
tools:context=".MainActivity">
<RelativeLayout
android:id="@+id/ll_net"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.TabLayout
android:id="@+id/tab"
android:layout_gravity="center_horizontal"
android:layout_centerHorizontal="true"
android:layout_width="wrap_content"
android:layout_height="144px"
app:tabPaddingEnd="-1px"
app:tabPaddingStart="-1px"
app:tabMaxWidth="600px"
app:tabMinWidth="80px"
app:tabIndicatorColor="@color/tab_slelect_text"
app:tabBackground="@null"
app:tabGravity="center"
android:nextFocusRight="@+id/tab"
android:nextFocusLeft="@+id/tab"
app:tabTextColor="@color/tab_normal_color"
app:tabSelectedTextColor="@color/tab_slelect_text"
app:tabRippleColor="@color/trans"
app:tabUnboundedRipple="true"
app:tabTextAppearance="@style/tabTextStyle"
app:tabMode="scrollable">
</android.support.design.widget.TabLayout>
<View
android:background="@color/lb_search_bar_text"
android:layout_width="match_parent"
android:layout_alignBottom="@+id/tab"
android:layout_marginTop="-2px"
android:layout_height="1px"/>
<android.support.v4.view.ViewPager
android:id="@+id/pager"
android:layout_below="@+id/tab"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v4.view.ViewPager>
</RelativeLayout>
<LinearLayout
android:id="@+id/ll_noNet"
android:visibility="gone"
android:orientation="vertical"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:src="@drawable/ic_network"
android:layout_width="300px"
android:layout_height="300px" />
<TextView
android:id="@+id/tv_tip"
android:textSize="20sp"
android:textColor="@color/title_color"
android:layout_marginTop="30px"
android:text="@string/no_net"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/btn_settingnet"
android:text="@string/no_net_button"
android:focusable="true"
android:gravity="center"
android:layout_marginTop="30px"
android:shadowColor="#59000000"
android:shadowDy="1"
android:shadowRadius="1"
android:textColor="@color/title_color"
android:textSize="18sp"
android:background="@drawable/detail_button_style"
android:layout_width="400px"
android:layout_height="100px" />
</LinearLayout>
</LinearLayout>
MainActivity.java
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewParent;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.google.gson.Gson;
import com.hisense.datautil.AutoUpdateService;
import com.hisense.movienow.bean.PatternBean;
import com.hisense.movienow.bean.TabItem;
import com.hisense.movienow.bean.TagBean;
import com.hisense.movienow.bean.TagName;
import com.hisense.movienow.utils.CommonUtils;
import com.hisense.movienow.utils.Constant;
import com.hisense.movienow.utils.SaveValue;
import com.hisense.movienow.widget.CustomRecycleView;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class MainActivity extends AppCompatActivity {
private final String TAG = "Hisense";
private String[] categorydata = {"Apple","Hisense","TCL","LG"};
public TabLayout tableLayout;
private ViewPager pager;
private List<TabItem> list = new ArrayList<>();
private ArrayList<Fragment> fragments = new ArrayList<>();
Context mContext;
private PatternBean patternBean;
private SaveValue saveValue;
private List<TagBean> tagBeanList = new ArrayList<>();
MovieFragmentPagerAdapter pagerAdapter;
long timestamp = 0;
String token = "";
private LinearLayout ll_noNet;
private RelativeLayout ll_net;
private TextView tv_tip,tv_button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//init tablayout and view pager
mContext = MainActivity.this;
saveValue = SaveValue.getInstance(mContext);
initView();
if (CommonUtils.getInstance(mContext).isNetworkConnected()) {
//init demo tab data
ll_net.setVisibility(View.VISIBLE);
ll_noNet.setVisibility(View.GONE);
getTabCate();
}else{
ll_noNet.setVisibility(View.VISIBLE);
ll_net.setVisibility(View.GONE);
}
}
public int position = 0;
public boolean isTabScroll = true;
private void initView(){
this.pager = (ViewPager) findViewById(R.id.pager);
this.tableLayout = (TabLayout) findViewById(R.id.tab);
// ViewCompat.setElevation(tableLayout, 100);
//设置tabLayout的分隔线
LinearLayout linearLayout = (LinearLayout) tableLayout.getChildAt(0);
linearLayout.setShowDividers(LinearLayout.SHOW_DIVIDER_MIDDLE);
linearLayout.setDividerDrawable(getResources().getDrawable(R.drawable.tablayout_divider_style));
linearLayout.setDividerPadding(12);
tableLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
Log.e(TAG,"onTabSelected tab.getPosition()="+tab.getPosition());
isTabScroll = true;
position = tab.getPosition();
pager.setCurrentItem(position);
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
Log.e(TAG,"onTabUnselected="+tab.getPosition());
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
Log.e(TAG,"onTabReselected="+tab.getContentDescription());
}
});
tableLayout.setOnKeyListener(new View.OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_DPAD_CENTER:
Log.e(TAG, "setOnKeyListener=======KEYCODE_DPAD_CENTER");
break;
case KeyEvent.KEYCODE_DPAD_UP:
Log.e(TAG, "setOnKeyListener=======KEYCODE_DPAD_UP");
break;
case KeyEvent.KEYCODE_DPAD_DOWN:
tableLayout.clearFocus();
isTabScroll = false;
tableLayout.setSelectedTabIndicatorColor(getResources().getColor(R.color.white));
tableLayout.setTabTextColors(getResources().getColor(R.color.tab_normal_color),getResources().getColor(R.color.white));
break;
case KeyEvent.KEYCODE_DPAD_LEFT:
if(position != 0) {
pager.setCurrentItem(position - 1);
}
break;
case KeyEvent.KEYCODE_DPAD_RIGHT:
pager.setCurrentItem(position+1);
break;
}
return false;
}
});
ll_net = findViewById(R.id.ll_net);
ll_noNet = findViewById(R.id.ll_noNet);
tv_tip = findViewById(R.id.tv_tip);
tv_button = findViewById(R.id.btn_settingnet);
tv_button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(tv_button.getText().toString().equals(getResources().getString(R.string.no_net_button))){
Intent intent = new Intent("android.settings.SETTINGS");
startActivity(intent);
}else{
getTabCate();
}
}
});
}
int defaultTab = 0;
int defaultTag = 0;
//获取标签数据,此处方法省略
private void getTabCate(){
……
}
//获取标签数据之后更新UI
private void showResponse(final String response, final int status){
runOnUiThread(new Runnable() {
@Override
public void run() {
if(status == 1){
//init moviefragment
initMovieFragmentData();
//set adapter for moive fragment
pagerAdapter = new MovieFragmentPagerAdapter(mContext,MainActivity.this.getSupportFragmentManager(), fragments, list);
pager.setAdapter(pagerAdapter);
pager.setCurrentItem(defaultTab);
//
tableLayout.setupWithViewPager(pager);
}else if(status == 100002){
token = CommonUtils.getInstance(mContext).getNewToken();
Constant.ACCESSTOKEN = token;
getTabCate();
}else {
// Toast.makeText(MainActivity.this,response+"",Toast.LENGTH_LONG).show();
ll_net.setVisibility(View.GONE);
ll_noNet.setVisibility(View.VISIBLE);
tv_tip.setText(getResources().getString(R.string.server_error));
tv_button.setText(getResources().getString(R.string.refresh));
}
}
});
}
private void initMovieFragmentData(){
fragments.clear();
for (int i=0;i<list.size();i++) {
Bundle data = new Bundle();
if(list.get(i).getTag_id() == 2){
HistoryFragment2 historyFragment = new HistoryFragment2();
fragments.add(historyFragment);
}
else {
data.putInt("categoryID", list.get(i).getTag_id());
// data.putInt("defaultTag",defaultTag);
data.putLong("timestamp",timestamp);
data.putString("token",token);
MovieFragment2 movieFragment = new MovieFragment2();
movieFragment.setArguments(data);
fragments.add(movieFragment);
}
}
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
Log.e(TAG,"keyevent======onKeyDown==="+isTabScroll);
switch(keyCode){
case KeyEvent.KEYCODE_DPAD_DOWN:
View view = getCurrentFocus();
if(isTabScroll){
isTabScroll = false;
tableLayout.clearFocus();
tableLayout.setSelectedTabIndicatorColor(getResources().getColor(R.color.white));
tableLayout.setTabTextColors(getResources().getColor(R.color.tab_normal_color),getResources().getColor(R.color.white));
// return true;
}
return false;
case KeyEvent.KEYCODE_DPAD_LEFT:
View viewl = getCurrentFocus();
if(isTabScroll){
if(position != 0){
// recomputeTlOffset1(position-1);
pager.setCurrentItem(position-1);
}
return false;
}else{
return false;
}
case KeyEvent.KEYCODE_DPAD_RIGHT:
View viewr = getCurrentFocus();
if(isTabScroll){
// recomputeTlOffset1(position+1);
pager.setCurrentItem(position+1);
return true;
}else{
return false;
}
case KeyEvent.KEYCODE_DPAD_UP:
View viewu = getCurrentFocus();
ViewParent parent = viewu.getParent();//.getParent().getParent();
if(position !=1 && CustomRecycleView.positon == 0){
tableLayout.requestFocus();
tableLayout.setSelectedTabIndicatorColor(getResources().getColor(R.color.tab_slelect_text));
tableLayout.setTabTextColors(getResources().getColor(R.color.tab_normal_color),getResources().getColor(R.color.tab_slelect_text));
isTabScroll = true;
return true;
}else if(position ==1 && HistoryFragment2.hisPosition == 0){//(CustomRecycleView.positon == 0 && position ==1){
HistoryFragment2 historyFragment = (HistoryFragment2)fragments.get(position);
historyFragment.onKeyDownFragment(keyCode, event);
return true;
}
break;
case KeyEvent.KEYCODE_DPAD_CENTER:
Log.e(TAG,"keyevent======onKeyDown==KEYCODE_DPAD_CENTER=");
break;
case KeyEvent.KEYCODE_BACK:
if(!isTabScroll){
tableLayout.requestFocus();
isTabScroll = true;
if(position == 1){
HistoryFragment2 historyFragment = (HistoryFragment2)fragments.get(position);
historyFragment.onKeyDownFragment(keyCode, event);
}
tableLayout.setSelectedTabIndicatorColor(getResources().getColor(R.color.tab_slelect_text));
tableLayout.setTabTextColors(getResources().getColor(R.color.tab_normal_color),getResources().getColor(R.color.tab_slelect_text));
return true;
}else{
finish();
}
break;
}
return super.onKeyDown(keyCode, event);
}
@Override
public boolean onKeyUp(int keyCode, KeyEvent event){
return super.onKeyUp(keyCode, event);
}
protected void onDestory(){
super.onDestroy();
System.exit(0);
}
public void onBackPressed(){
super.onBackPressed();
Log.e(TAG,"onBackPressed");
}
public Handler myHandler = new Handler(){
@Override
public void handleMessage(Message message){
switch (message.what){
case Constant.NO_NET:
ll_net.setVisibility(View.GONE);
ll_noNet.setVisibility(View.VISIBLE);
tv_tip.setText(getResources().getString(R.string.no_net));
tv_button.setText(getResources().getString(R.string.no_net_button));
break;
case Constant.SERVER_ERROR:
ll_net.setVisibility(View.GONE);
ll_noNet.setVisibility(View.VISIBLE);
tv_tip.setText(getResources().getString(R.string.server_error));
tv_button.setText(getResources().getString(R.string.refresh));
break;
}
}
};
}
涉及到的知识点:
1. 按键的处理:
下方的fragment中有横向的列表,为了避免列表滚动与tab的滚动冲突,设置标志位isTabScroll,在onKeyDown中,当为true时,返回true,按键拦截,在tabLayout上左右滑动,,当为false时,返回false,按键下发,焦点在fragment的列表中左右滑动,
按下键时,焦点移动到下方的列表中,所以按键要分发下去,返回false,同时isTabScroll设为false,tabLayout中的相应tab,变为选中但失去焦点状态,即tab的文本和指示线颜色设为白色。当焦点在下方列表的第一行,按上键时,焦点在最上层的tabLayout上,按键拦截返回true,同时isTabScroll设为true,tabLayout中的相应tab,变为焦点选中状态,即文本和指示线的颜色变为绿色。
按返回键时,当焦点在tabLayout上时,直接退出应用,当焦点在下方列表中时,焦点移动到tabLayout上,isTabScroll设为true,按键拦截,返回true
tabLayout的onKeyListener,当焦点在的时候,按下键,可以直接走onKeyDown,这里不需要设置,但左右键都得设置。
2. tabLayout分隔线的设置
分隔线可以用tabPaddingStart和tabPaddingEnd来设置,当要求间距为72px时,start和end各设为36px,但是这样指示线的长度会包含间距的长度
另外一种方法:
LinearLayout linearLayout = (LinearLayout) tableLayout.getChildAt(0);
linearLayout.setShowDividers(LinearLayout.SHOW_DIVIDER_MIDDLE);
linearLayout.setDividerDrawable(getResources().getDrawable(R.drawable.tablayout_divider_style));
linearLayout.setDividerPadding(12);
作为分隔线的图片,必须有宽高大小,如果是用shape写出来的图片,要在shape中设置它的size,否则不起作用。
3. tab文字颜色和指示线颜色的变化
在1中已经写明,当焦点在tabLayout中时,颜色都是绿色,选中但焦点不在时,颜色是纯白色,默认颜色是带点灰色的白色。
tableLayout.setSelectedTabIndicatorColor(getResources().getColor(R.color.tab_slelect_text));
tableLayout.setTabTextColors(getResources().getColor(R.color.tab_normal_color),getResources().getColor(R.color.tab_slelect_text));
暂时总结这时,以后更新。