1ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu/* 2ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu * Copyright (C) 2013 The Android Open Source Project 3ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu * 4ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu * Licensed under the Apache License, Version 2.0 (the "License"); 5ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu * you may not use this file except in compliance with the License. 6ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu * You may obtain a copy of the License at 7ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu * 8ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu * http://www.apache.org/licenses/LICENSE-2.0 9ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu * 10ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu * Unless required by applicable law or agreed to in writing, software 11ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu * distributed under the License is distributed on an "AS IS" BASIS, 12ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu * See the License for the specific language governing permissions and 14ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu * limitations under the License. 15ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu */ 16ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu 17ccea98979aa38d1061ae38a31271040a698c9d87Dake Gupackage com.example.android.leanback; 18ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu 19ccea98979aa38d1061ae38a31271040a698c9d87Dake Guimport android.app.Activity; 20ccea98979aa38d1061ae38a31271040a698c9d87Dake Guimport android.content.Intent; 21ccea98979aa38d1061ae38a31271040a698c9d87Dake Guimport android.graphics.Color; 22ccea98979aa38d1061ae38a31271040a698c9d87Dake Guimport android.os.Bundle; 23b7087e036a48f5a3db28d02ff7f9b97fbbc46c4fDake Guimport android.support.v17.leanback.widget.HorizontalGridView; 24b7087e036a48f5a3db28d02ff7f9b97fbbc46c4fDake Guimport android.support.v17.leanback.widget.OnChildViewHolderSelectedListener; 25b7087e036a48f5a3db28d02ff7f9b97fbbc46c4fDake Guimport android.support.v7.widget.RecyclerView; 26ccea98979aa38d1061ae38a31271040a698c9d87Dake Guimport android.util.Log; 27ccea98979aa38d1061ae38a31271040a698c9d87Dake Guimport android.view.View; 28ccea98979aa38d1061ae38a31271040a698c9d87Dake Guimport android.view.View.OnClickListener; 29ccea98979aa38d1061ae38a31271040a698c9d87Dake Guimport android.view.View.OnFocusChangeListener; 30ccea98979aa38d1061ae38a31271040a698c9d87Dake Guimport android.view.ViewGroup; 31ccea98979aa38d1061ae38a31271040a698c9d87Dake Guimport android.widget.TextView; 32ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu 33ccea98979aa38d1061ae38a31271040a698c9d87Dake Gupublic class HorizontalGridTestActivity extends Activity { 34ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu private static final String TAG = "HorizontalGridTestActivity"; 35ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu private static final boolean DEBUG = true; 36ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu private static final String SELECT_ACTION = "android.test.leanback.widget.SELECT"; 37ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu private static final int NUM_ITEMS = 100; 38ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu private static final boolean STAGGERED = true; 39ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu 40ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu private HorizontalGridView mHorizontalGridView; 41ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu 42ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu private RecyclerView.OnScrollListener mScrollListener = new RecyclerView.OnScrollListener() { 43ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu @Override 44ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu public void onScrollStateChanged(RecyclerView recyclerView, int newState) { 45ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu if (DEBUG) { 46ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu final String[] stateNames = { "IDLE", "DRAGGING", "SETTLING" }; 47ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu Log.v(TAG, "onScrollStateChanged " 48ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu + (newState < stateNames.length ? stateNames[newState] : newState)); 49ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu } 50ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu } 51ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu }; 52ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu 53ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu private View createView() { 54ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu View view = getLayoutInflater().inflate(R.layout.horizontal_grid, null, false); 55ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu mHorizontalGridView = (HorizontalGridView) view.findViewById(R.id.gridview); 56ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu 57ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu mHorizontalGridView.setWindowAlignment(HorizontalGridView.WINDOW_ALIGN_BOTH_EDGE); 58ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu mHorizontalGridView.setWindowAlignmentOffsetPercent(35); 59b7087e036a48f5a3db28d02ff7f9b97fbbc46c4fDake Gu mHorizontalGridView.setOnChildViewHolderSelectedListener( 60b7087e036a48f5a3db28d02ff7f9b97fbbc46c4fDake Gu new OnChildViewHolderSelectedListener() { 61b7087e036a48f5a3db28d02ff7f9b97fbbc46c4fDake Gu @Override 62b7087e036a48f5a3db28d02ff7f9b97fbbc46c4fDake Gu public void onChildViewHolderSelected(RecyclerView parent, 63b7087e036a48f5a3db28d02ff7f9b97fbbc46c4fDake Gu RecyclerView.ViewHolder child, 64b7087e036a48f5a3db28d02ff7f9b97fbbc46c4fDake Gu int position, int subposition) { 65b7087e036a48f5a3db28d02ff7f9b97fbbc46c4fDake Gu if (DEBUG) Log.d(TAG, "onChildSelected position=" + position); 66b7087e036a48f5a3db28d02ff7f9b97fbbc46c4fDake Gu } 67b7087e036a48f5a3db28d02ff7f9b97fbbc46c4fDake Gu 68b7087e036a48f5a3db28d02ff7f9b97fbbc46c4fDake Gu }); 69ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu return view; 70ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu } 71ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu 72ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu @Override 73ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu protected void onCreate(Bundle savedInstanceState) { 74ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu super.onCreate(savedInstanceState); 75ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu 76ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu if (DEBUG) Log.v(TAG, "onCreate"); 77ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu 78ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu RecyclerView.Adapter adapter = new MyAdapter(); 79ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu 80ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu View view = createView(); 81ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu 82ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu mHorizontalGridView.setAdapter(new MyAdapter()); 83ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu setContentView(view); 84ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu 85b7087e036a48f5a3db28d02ff7f9b97fbbc46c4fDake Gu mHorizontalGridView.addOnScrollListener(mScrollListener); 86ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu } 87ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu 88ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu @Override 89ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu protected void onNewIntent(Intent intent) { 90ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu if (DEBUG) Log.v(TAG, "onNewIntent " + intent); 91ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu if (intent.getAction().equals(SELECT_ACTION)) { 92ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu int position = intent.getIntExtra("SELECT_POSITION", -1); 93ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu if (position >= 0) { 94ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu mHorizontalGridView.setSelectedPosition(position); 95ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu } 96ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu } 97ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu super.onNewIntent(intent); 98ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu } 99ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu 100ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu private OnFocusChangeListener mItemFocusChangeListener = new OnFocusChangeListener() { 101ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu 102ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu @Override 103ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu public void onFocusChange(View v, boolean hasFocus) { 104ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu if (hasFocus) { 105ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu v.setBackgroundColor(Color.YELLOW); 106ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu } else { 107ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu v.setBackgroundColor(Color.LTGRAY); 108ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu } 109ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu } 110ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu }; 111ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu 112ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu private OnClickListener mItemClickListener = new OnClickListener() { 113ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu @Override 114ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu public void onClick(View v) { 115ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu mHorizontalGridView.getAdapter().notifyDataSetChanged(); 116ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu } 117ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu }; 118ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu 119ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu class MyAdapter extends RecyclerView.Adapter { 120ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu 121ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu private int[] mItemLengths; 122ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu 123ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu MyAdapter() { 124ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu mItemLengths = new int[NUM_ITEMS]; 125ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu for (int i = 0; i < mItemLengths.length; i++) { 126ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu mItemLengths[i] = STAGGERED ? (int)(Math.random() * 180) + 180 : 240; 127ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu } 128ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu } 129ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu 130ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu @Override 131ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 132ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu if (DEBUG) Log.v(TAG, "createViewHolder " + viewType); 133ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu TextView textView = new TextView(parent.getContext()); 134ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu textView.setTextColor(Color.BLACK); 135ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu textView.setFocusable(true); 136ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu textView.setFocusableInTouchMode(true); 137ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu textView.setOnFocusChangeListener(mItemFocusChangeListener); 138ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu textView.setOnClickListener(mItemClickListener); 139ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu return new ViewHolder(textView); 140ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu } 141ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu 142ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu @Override 143ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu public void onBindViewHolder(RecyclerView.ViewHolder baseHolder, int position) { 144ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu if (DEBUG) Log.v(TAG, "bindViewHolder " + position + " " + baseHolder); 145ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu ViewHolder holder = (ViewHolder) baseHolder; 146ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu ((TextView) holder.itemView).setText("Item "+position); 147ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu holder.itemView.setBackgroundColor(Color.LTGRAY); 148ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu holder.itemView.setLayoutParams(new ViewGroup.MarginLayoutParams(mItemLengths[position], 149ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu 80)); 150ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu } 151ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu 152ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu @Override 153ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu public int getItemCount() { 154ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu return mItemLengths.length; 155ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu } 156ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu } 157ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu 158ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu static class ViewHolder extends RecyclerView.ViewHolder { 159ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu 160ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu public ViewHolder(View v) { 161ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu super(v); 162ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu } 163ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu } 164ccea98979aa38d1061ae38a31271040a698c9d87Dake Gu} 165