HorizontalListView
功能列表:
- 横向显示
- 子视图的宽度设置有效
- match_parent : 与HorizontalListView的宽度相同
- wrap_content : 宽度为自己所需宽度
- 固定数值 : 宽度为固定值
- 支持setSelection(int) setSelectionFromLeft(int, int)
- 支持scrollTo(int)
- 支持RequestFreeze
- 通常用于刷新数据,固定当前子视图的位置。
- 支持OnScrollListener
请从github上下载源码。本文后面贴的代码不同步更新了。
HorzitontalListView Source code
唠叨一下,想直接看源码的可以跳过
水平的ListView控件。很常用。但目前android widget并没有该控件。
之前用过HorizontalScrollView 写过。改动起来很麻烦。自己写Adapter 自己写Recycle 以及常用方法如setSelection() 等等。
打算照着ListView的思路写一个Horizontal的。上网搜搜发现github上有一个兄弟写了。网址附上:https://github.com/dinocore1/DevsmartLib-Android/tree/master/demo/src/com/devsmart/demo
用的时候发现有bug,而且显示效果并不是我想要的(与ListView相比较,仅仅是方向变了)。而且并不支持setSelection(int) 故动手改了改,
尊重原著,注释紧将版本号改为1.5.1(原为1.5)
变量名与取值尽量与ListView一致,方便阅读。
并未实现所有接口,使用的时候注意哦。
code:

1 /*
2 * HorizontalListView.java v1.5.1
3 *
4 * Copyright (c) 2011
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 *
24 */
25
26 import java.util.LinkedList;
27 import java.util.Queue;
28
29 import android.content.Context;
30 import android.database.DataSetObserver;
31 import android.graphics.Rect;
32 import android.util.AttributeSet;
33 import android.view.GestureDetector;
34 import android.view.GestureDetector.OnGestureListener;
35 import android.view.MotionEvent;
36 import android.view.View;
37 import android.view.ViewGroup;
38 import android.widget.AbsListView;
39 import android.widget.AdapterView;
40 import android.widget.ListAdapter;
41 import android.widget.Scroller;
42
43 public class HorizontalListView extends AdapterView<ListAdapter> {
44
45 /**
46 * Regular layout - usually an unsolicited layout from the view system
47 */
48 static final int LAYOUT_NORMAL = 0;
49
50 /**
51 * Make a mSelectedItem appear in a specific location and build the rest of
52 * the views from there. The top is specified by mSpecificTop.
53 */
54 static final int LAYOUT_SPECIFIC = 4;
55
56 /**
57 * Layout to sync as a result of a data change. Restore mSyncPosition to have its top
58 * at mSpecificTop
59 */
60 static final int LAYOUT_SYNC = 5;
61
62 /**
63 * Controls how the next layout will happen
64 */
65 int mLayoutMode = LAYOUT_NORMAL;
66
67
68 public boolean mAlwaysOverrideTouch = true;
69
70 protected ListAdapter mAdapter;
71 protected Scroller mScroller;
72 private GestureDetector mGesture;
73
74 private int mLeftViewIndex = -1;
75 private int mRightViewIndex = 0;
76
77 private int mMaxX = Integer.MAX_VALUE;
78 private int mMinX = Integer.MIN_VALUE;
79 protected int mCurrentX;
80 protected int mNextX;
81 private int mDisplayOffset = 0;
82
83 private Queue<View> mRemovedViewQueue = new LinkedList<View>();
84
85 private OnItemSelectedListener mOnItemSelected;
86 private OnItemClickListener mOnItemClicked;
87 private OnItemLongClickListener mOnItemLongClicked;
88
89 private boolean mDataChanged = false;
90
91 private int mFirstPosition = 0;
92
93 public HorizontalListView(Context context, AttributeSet attrs) {
94 super(context, attrs);
95 initView();
96 }
97
98 private synchronized void initView() {
99 mLeftViewIndex = -1;
100 mRightViewIndex = 0;
101 mDisplayOffset = 0;
102 mCurrentX = 0;
103 mNextX = 0;
104 mFirstPosition = 0;
105 mSpecificPosition = 0;
106 mSpecificLeft = 0;
107 mMaxX = Integer.MAX_VALUE;
108 mMinX = Integer.MIN_VALUE;
109 mScroller = new Scroller(getContext());
110 mGesture = new GestureDetector(getContext(), mOnGesture);
111 }
112
113 private synchronized void initViewForSpecific() {
114 mLeftViewIndex = mSpecificPosition - 1;
115 mRightViewIndex = mSpecificPosition + 1;
116 mFirstPosition = mSpecificPosition;
117 mDisplayOffset = 0;
118 mCurrentX = 0;
119 mNextX = 0;
120 mMaxX = Integer.MAX_VALUE;
121 mScroller = new Scroller(getContext());
122 mGesture = new GestureDetector(getContext(), mOnGesture);
123 }
124
125 @Override
126 public void setOnItemSelectedListener(
127 AdapterView.OnItemSelectedListener listener) {
128 mOnItemSelected = listener;
129 }
130
131 @Override
132 public void setOnItemClickListener(AdapterView.OnItemClickListener listener) {
133 mOnItemClicked = listener;
134 }
135
136 @Override
137 public void setOnItemLongClickListener(
138 AdapterView.OnItemLongClickListener listener) {
139 mOnItemLongClicked = listener;
140 }
141
142 private DataSetObserver mDataObserver = new DataSetObserver() {
143
144 @Override
145 public void onChanged() {
146 synchronized (HorizontalListView.this) {
147 mDataChanged = true;
148 }
149 invalidate();
150 requestLayout();
151 }
152
153 @Override
154 public void onInvalidated() {
155 reset();
156 invalidate();
157 requestLayout();
158 }
159
160 };
161
162
163
164 private int mSpecificLeft;
165
166 private int mSpecificPosition;
167
168 @Override
169 public ListAdapter getAdapter() {
170 return mAdapter;
171 }
172
173 @Override
174 public View getSelectedView() {
175 // TODO: implement
176 return null;
177 }
178
179 @Override
180 public void setAdapter(ListAdapter adapter) {
181 if (mAdapter != null) {
182 mAdapter.unregisterDataSetObserver(mDataObserver);
183 }
184 mAdapter = adapter;
185 mAdapter.registerDataSetObserver(mDataObserver);
186 reset();
187 }
188
189 private synchronized void reset() {
190 initView();
191 removeAllViewsInLayout();
192 requestLayout();
193 }
194
195 @Override
196 public int getFirstVisiblePosition() {
197 return mFirstPosition;
198 }
199
200 @Override
201 public void setSelection(int position) {
202 setSelectionFromLeft(position, 0);
203 }
204
205 /**
206 * Sets the selected item and positions the selection y pixels from the left edge
207 * of the ListView. (If in touch mode, the item will not be selected but it will
208 * still be positioned appropriately.)
209 *
210 * @param position Index (starting at 0) of the data item to be selected.
211 * @param x The distance from the left edge of the ListView (plus padding) that the
212 * item will be positioned.
213 */
214 public void setSelectionFromLeft(int position, int x) {
215 if (mAdapter == null) {
216 return;
217 }
218
219 if (!isInTouchMode()) {
220 position = lookForSelectablePosition(position, true);
221 }
222
223 if (position >= 0) {
224 mLayoutMode = LAYOUT_SPECIFIC;
225 mSpecificPosition = position;
226 mSpecificLeft = getPaddingLeft() + x;
227
228 requestLayout();
229 }
230 }
231
232
233 /**
234 * Find a position that can be selected (i.e., is not a separator).
235 *
236 * @param position The starting position to look at.
237 * @param lookDown Whether to look down for other positions.
238 * @return The next selectable position starting at position and then searching either up or
239 * down. Returns {@link #INVALID_POSITION} if nothing can be found.
240 */
241 int lookForSelectablePosition(int position, boolean lookDown) {
242 final ListAdapter adapter = mAdapter;
243 if (adapter == null || isInTouchMode()) {
244 return INVALID_POSITION;
245 }
246
247 final int count = adapter.getCount();
248 if (!adapter.areAllItemsEnabled()) {
249 if (lookDown) {
250 position = Math.max(0, position);
251 while (position < count && !adapter.isEnabled(position)) {
252 position++;
253 }
254 } else {
255 position = Math.min(position, count - 1);
256 while (position >= 0 && !adapter.isEnabled(position)) {
257 position--;
258 }
259 }
260
261 if (position < 0 || position >= count) {
262 return INVALID_POSITION;
263 }
264 return position;
265 } else {
266 if (position < 0 || position >= count) {
267 return INVALID_POSITION;
268 }
269 return position;
270 }
271 }
272
273 private void addAndMeasureChild(final View child, int viewPos) {
274 LayoutParams params = (LayoutParams) child.getLayoutParams();
275 params = new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
276 ViewGroup.LayoutParams.MATCH_PARENT);
277
278 addViewInLayout(child, viewPos, params, true);
279
280 int heightMeasureSpec = MeasureSpec.makeMeasureSpec(getMeasuredHeight(),
281 MeasureSpec.EXACTLY);
282 int childHeightSpec = ViewGroup.getChildMeasureSpec(heightMeasureSpec,
283 getPaddingTop() + getPaddingBottom(), params.height);
284 int childWidthSpec = MeasureSpec.makeMeasureSpec(
285 params.width > 0 ? params.width : 0, MeasureSpec.UNSPECIFIED);
286 child.measure(childWidthSpec, childHeightSpec);
287
288 }
289
290
291 @Override
292 protected synchronized void onLayout(boolean changed, int left, int top,
293 int right, int bottom) {
294 super.onLayout(changed, left, top, right, bottom);
295
296 if (mAdapter == null) {
297 return;
298 }
299
300 if (mDataChanged) {
301 int oldCurrentX = mCurrentX;
302 initView();
303 removeAllViewsInLayout();
304 mNextX = oldCurrentX;
305 mDataChanged = false;
306 }
307
308 if (mScroller.computeScrollOffset()) {
309 int scrollx = mScroller.getCurrX();
310 mNextX = scrollx;
311 }
312
313 if (mNextX <= mMinX) {
314 mNextX = mMinX;
315 mScroller.forceFinished(true);
316 }
317 if (mNextX >= mMaxX) {
318 mNextX = mMaxX;
319 mScroller.forceFinished(true);
320 }
321
322 int dx = 0;
323 switch (mLayoutMode) {
324 case LAYOUT_SPECIFIC:
325 dx = mSpecificLeft;
326 detachAllViewsFromParent();
327 initViewForSpecific();
328 fillSpecific(mSpecificPosition, dx);
329 positionItems(dx);
330
331 mNextX = mSpecificLeft;
332 mSpecificPosition = -1;
333 mSpecificLeft = 0;
334 break;
335 default:
336 dx = mCurrentX - mNextX;
337 removeNonVisibleItems(dx);
338 fillList(dx);
339 positionItems(dx);
340 }
341
342 mCurrentX = mNextX;
343 mLayoutMode = LAYOUT_NORMAL;
344
345 if (!mScroller.isFinished()) {
346 post(new Runnable() {
347
348 @Override
349 public void run() {
350 requestLayout();
351 }
352 });
353
354 }
355 }
356
357 private void fillList(final int dx) {
358 int edge = 0;
359 View child = getChildAt(getChildCount() - 1);
360 if (child != null) {
361 edge = child.getRight();
362 }
363 fillListRight(edge, dx);
364
365 edge = 0;
366 child = getChildAt(0);
367 if (child != null) {
368 edge = child.getLeft();
369 }
370 fillListLeft(edge, dx);
371
372 }
373
374 private void fillSpecific(int position, int top) {
375 View child = mAdapter.getView(position, null, null);
376 if (child == null) return;
377 addAndMeasureChild(child, -1);
378 int edge = 0;
379 if (child != null) {
380 edge = child.getRight();
381 fillListRight(edge, top);
382 edge = child.getLeft();
383 fillListLeft(edge, top);
384 }
385 }
386
387 private void fillListRight(int rightEdge, final int dx) {
388 while (rightEdge + dx < getWidth()
389 && mRightViewIndex < mAdapter.getCount()) {
390
391 View child = mAdapter.getView(mRightViewIndex,
392 mRemovedViewQueue.poll(), this);
393 addAndMeasureChild(child, -1);
394 rightEdge += child.getMeasuredWidth();
395
396 if (mRightViewIndex == mAdapter.getCount() - 1) {
397 mMaxX = mCurrentX + rightEdge - getWidth();
398 }
399
400 if (mMaxX < 0) {
401 mMaxX = 0;
402 }
403 mRightViewIndex++;
404 }
405
406 }
407
408 private void fillListLeft(int leftEdge, final int dx) {
409 while (leftEdge + dx > 0 && mLeftViewIndex >= 0) {
410 View child = mAdapter.getView(mLeftViewIndex,
411 mRemovedViewQueue.poll(), this);
412 addAndMeasureChild(child, 0);
413 leftEdge -= child.getMeasuredWidth();
414 if (mLeftViewIndex == 0) {
415 mMinX = mCurrentX + leftEdge;
416 }
417 if (mMinX > 0) {
418 mMinX = 0;
419 }
420 mLeftViewIndex--;
421 mDisplayOffset -= child.getMeasuredWidth();
422 }
423 mFirstPosition = mLeftViewIndex + 1;
424 }
425
426 private void removeNonVisibleItems(final int dx) {
427 View child = getChildAt(0);
428 while (child != null && child.getRight() + dx <= 0) {
429 mDisplayOffset += child.getMeasuredWidth();
430 mRemovedViewQueue.offer(child);
431 removeViewInLayout(child);
432 mLeftViewIndex++;
433 child = getChildAt(0);
434
435 }
436
437 child = getChildAt(getChildCount() - 1);
438 while (child != null && child.getLeft() + dx >= getWidth()) {
439 mRemovedViewQueue.offer(child);
440 removeViewInLayout(child);
441 mRightViewIndex--;
442 child = getChildAt(getChildCount() - 1);
443 }
444 }
445
446 private void positionItems(final int dx) {
447 if (getChildCount() > 0) {
448 mDisplayOffset += dx;
449 int left = mDisplayOffset;
450 for (int i = 0; i < getChildCount(); i++) {
451 View child = getChildAt(i);
452 int childWidth = child.getMeasuredWidth();
453 child.layout(left, 0, left + childWidth,
454 child.getMeasuredHeight());
455 left += childWidth + child.getPaddingRight();
456 }
457 }
458 }
459
460 public synchronized void scrollTo(int x) {
461 mScroller.startScroll(mNextX, 0, x - mNextX, 0);
462 requestLayout();
463 }
464
465 @Override
466 public boolean dispatchTouchEvent(MotionEvent ev) {
467 boolean handled = super.dispatchTouchEvent(ev);
468 handled |= mGesture.onTouchEvent(ev);
469 return handled;
470 }
471
472 protected boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
473 float velocityY) {
474 synchronized (HorizontalListView.this) {
475 mScroller.fling(mNextX, 0, (int) -velocityX, 0, mMinX, mMaxX, 0, 0);
476 }
477 requestLayout();
478
479 return true;
480 }
481
482 protected boolean onDown(MotionEvent e) {
483 mScroller.forceFinished(true);
484 return true;
485 }
486
487 private OnGestureListener mOnGesture = new GestureDetector.SimpleOnGestureListener() {
488
489 @Override
490 public boolean onDown(MotionEvent e) {
491 return HorizontalListView.this.onDown(e);
492 }
493
494 @Override
495 public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
496 float velocityY) {
497 return HorizontalListView.this
498 .onFling(e1, e2, velocityX, velocityY);
499 }
500
501 @Override
502 public boolean onScroll(MotionEvent e1, MotionEvent e2,
503 float distanceX, float distanceY) {
504
505 synchronized (HorizontalListView.this) {
506 mNextX += (int) distanceX;
507 }
508 requestLayout();
509
510 return true;
511 }
512
513 @Override
514 public boolean onSingleTapConfirmed(MotionEvent e) {
515 for (int i = 0; i < getChildCount(); i++) {
516 View child = getChildAt(i);
517 if (isEventWithinView(e, child)) {
518 if (mOnItemClicked != null) {
519 mOnItemClicked.onItemClick(HorizontalListView.this,
520 child, mLeftViewIndex + 1 + i,
521 mAdapter.getItemId(mLeftViewIndex + 1 + i));
522 }
523 if (mOnItemSelected != null) {
524 mOnItemSelected.onItemSelected(HorizontalListView.this,
525 child, mLeftViewIndex + 1 + i,
526 mAdapter.getItemId(mLeftViewIndex + 1 + i));
527 }
528 break;
529 }
530
531 }
532 return true;
533 }
534
535 @Override
536 public void onLongPress(MotionEvent e) {
537 int childCount = getChildCount();
538 for (int i = 0; i < childCount; i++) {
539 View child = getChildAt(i);
540 if (isEventWithinView(e, child)) {
541 if (mOnItemLongClicked != null) {
542 mOnItemLongClicked.onItemLongClick(
543 HorizontalListView.this, child, mLeftViewIndex
544 + 1 + i,
545 mAdapter.getItemId(mLeftViewIndex + 1 + i));
546 }
547 break;
548 }
549
550 }
551 }
552
553 private boolean isEventWithinView(MotionEvent e, View child) {
554 Rect viewRect = new Rect();
555 int[] childPosition = new int[2];
556 child.getLocationOnScreen(childPosition);
557 int left = childPosition[0];
558 int right = left + child.getWidth();
559 int top = childPosition[1];
560 int bottom = top + child.getHeight();
561 viewRect.set(left, top, right, bottom);
562 return viewRect.contains((int) e.getRawX(), (int) e.getRawY());
563 }
564 };
565
566 }
Demo code:

1 package com.tangyu.component.test;
2
3 import com.tangyu.component.R;
4 import com.tangyu.component.Util;
5 import com.tangyu.component.view.HorizontalListView;
6
7 import android.app.Activity;
8 import android.os.Bundle;
9 import android.os.Handler;
10 import android.view.View;
11 import android.widget.AbsListView.LayoutParams;
12 import android.widget.AdapterView;
13 import android.widget.AdapterView.OnItemClickListener;
14 import android.widget.ArrayAdapter;
15
16 public class TestHorizontalListView extends Activity {
17
18 private HorizontalListView hListView;
19
20 Handler handler = new Handler() {
21 public void handleMessage(android.os.Message msg) {
22 final int position = hListView.getFirstVisiblePosition();
23 hListView.setSelection(position + 1);
24 sendEmptyMessageDelayed(0, 1500);
25 };
26 };
27
28 @Override
29 protected void onCreate(Bundle savedInstanceState) {
30 super.onCreate(savedInstanceState);
31 hListView = getHListView();
32 setContentView(hListView);
33
34 hListView.setAdapter(new ArrayAdapter<String>(this, R.layout.simple_list_item_1, mStringMores));
35 hListView.setOnItemClickListener(new OnItemClickListener() {
36
37 @Override
38 public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
39 long arg3) {
40 // TODO Auto-generated method stub
41 final int position = hListView.getFirstVisiblePosition();
42 Util.toast(TestHorizontalListView.this, "first = " + (position + 1) + " cur = " + (arg2 + 1), true);
43 handler.removeMessages(0);
44 }
45 });
46 }
47
48 public void onWindowFocusChanged(boolean hasFocus) {
49 super.onWindowFocusChanged(hasFocus);
50 if (hasFocus) {
51 hListView.setSelectionFromLeft(5, 0);
52 handler.sendEmptyMessageDelayed(0, 1500);
53 }
54 };
55
56 HorizontalListView getHListView() {
57 HorizontalListView listView = new HorizontalListView(this, null);
58 listView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
59 LayoutParams.MATCH_PARENT));
60 listView.setBackgroundColor(0x33FF0000);
61 return listView;
62 }
63
64 private String[] mStringMores = {"1 : Beyaz Peynir",
65 "2 : Harbourne Blue",
66 "3 : Doolin",
67 "4 : Cougar Gold",
68 "5 : Blue Castello",
69 "6 : Appenzell",
70 "7 : Rouleau De Beaulieu",
71 "8 : Ubriaco",
72 "9 : Evansdale Farmhouse Brie",
73 "10 : Mimolette",
74 "11 : Dreux a la Feuille",
75 "12 : Le Roule",
76 "13 : Seriously Strong Cheddar",
77 "14 : Bosworth",
78 "15 : Cream Havarti",
79 "16 : Ile d'Yeu",
80 "17 : Mont D'or Lyonnais",
81 "18 : Hubbardston Blue Cow",
82 "19 : Ardrahan",
83 "20 : Duroblando",
84 "21 : Provolone (Australian)",
85 "22 : Queso Fresco (Adobera)",
86 "23 : Mozzarella (Australian)",
87 "24 : Fiore Sardo",
88 "25 : Brick",
89 "26 : Maribo",
90 "27 : Danablu (Danish Blue)",
91 "28 : Provolone",
92 "29 : Crottin de Chavignol",
93 "30 : Pant ys Gawn",
94 "31 : Anejo Enchilado",
95 "32 : Schloss",
96 "33 : Bishop Kennedy",
97 "34 : Sirene",
98 "35 : Brebis du Lavort",
99 "36 : Llanboidy",
100 "37 : Exmoor Blue",
101 "38 : Yarg Cornish",
102 "39 : Canadian Cheddar",
103 "40 : Boulette d'Avesnes",
104 "41 : Cypress Grove Chevre",
105 "42 : Queso Majorero",
106 "43 : Gruyere",
107 "44 : Jindi Brie",
108 "45 : Ossau-Iraty",
109 "46 : Langres",
110 "47 : Fondant de Brebis",
111 "48 : Pasteurized Processed",
112 "49 : L'Ecir de l'Aubrac",
113 "50 : Monastery Cheeses",
114 "51 : Sainte Maure",
115 "52 : Rollot",
116 "53 : Swaledale",
117 "54 : Coeur de Camembert au Calvados",
118 "55 : Beauvoorde",
119 "56 : Leafield",
120 "57 : Bavarian Bergkase",
121 "58 : Caprice des Dieux",
122 "59 : Pecorino Romano",
123 "60 : Myzithra",
124 "61 : Feta (Australian)",
125 "62 : Caciotta",
126 "63 : Afuega'l Pitu",
127 "64 : Bleu de Laqueuille",
128 "65 : Maytag Blue",
129 "66 : Bleu de Septmoncel",
130 "67 : Lairobell",
131 "68 : Dauphin",
132 "69 : Coverdale",
133 "70 : Mozzarella di Bufala",
134 "71 : Herve",
135 "72 : Autun",
136 "73 : Bresse Bleu",
137 "74 : Bierkase",
138 "75 : Postel",
139 "76 : Buxton Blue",
140 "77 : Castelo Branco",
141 "78 : Tomme de Chevre",
142 "79 : Queso Jalapeno",
143 "80 : Matocq",
144 "81 : Regal de la Dombes",
145 "82 : Idaho Goatster",
146 "83 : Lanark Blue",
147 "84 : Acorn",
148 "85 : Trappe (Veritable)",
149 "86 : Romans Part Dieu",
150 "87 : Casciotta di Urbino",
151 "88 : Bryndza",
152 "89 : Perail de Brebis",
153 "90 : Galette du Paludier",
154 "91 : Gouda",
155 "92 : Mahoe Aged Gouda",
156 "93 : Chaource",
157 "94 : Bleu Des Causses",
158 "95 : Kadchgall",
159 "96 : Feta",
160 "97 : Orkney Extra Mature Cheddar",
161 "98 : Mozzarella Fresh, in water",
162 "99 : Liptauer",
163 "100 : Murol",
164 "101 : Aromes au Gene de Marc",
165 "102 : Petit Pardou",
166 "103 : Cooleney",
167 "104 : Saint-Paulin",
168 "105 : Gorgonzola",
169 "106 : Queso del Montsec",
170 "107 : Pate de Fromage",
171 "108 : Kaseri",
172 "109 : Fontina Val d'Aosta",
173 "110 : Spenwood",
174 "111 : Fromage Corse",
175 "112 : Fynbo",
176 "113 : Brebis du Puyfaucon",
177 "114 : Bonchester",
178 "115 : Weichkaese",
179 "116 : Fromage de Montagne de Savoie",
180 "117 : Rabacal",
181 "118 : Scamorza",
182 "119 : Dunbarra",
183 "120 : Friesekaas",
184 "121 : Abbaye du Mont des Cats",
185 "122 : Sourire Lozerien",
186 "123 : Shropshire Blue",
187 "124 : Klosterkaese",
188 "125 : Leerdammer",
189 "126 : Tetilla",
190 "127 : Grana Padano",
191 "128 : Castelleno",
192 "129 : Aubisque Pyrenees",
193 "130 : Bra",
194 "131 : Bleu de Gex",
195 "132 : Toscanello",
196 "133 : Leicester",
197 "134 : Graddost",
198 "135 : Gammelost",
199 "136 : Saaland Pfarr",
200 "137 : Broccio Demi-Affine",
201 "138 : Cornish Pepper",
202 "139 : Leyden",
203 "140 : Oszczypek",
204 "141 : Tillamook Cheddar",
205 "142 : Fourme de Montbrison",
206 "143 : Peekskill Pyramid",
207 "144 : Saint-Marcellin",
208 "145 : Sancerre",
209 "146 : Baguette Laonnaise",
210 "147 : Greve",
211 "148 : Niolo",
212 "149 : Ami du Chambertin",
213 "150 : Pyramide",
214 "151 : Cerney",
215 "152 : Neufchatel (Australian)",
216 "153 : King Island Cape Wickham Brie",
217 "154 : Maasdam",
218 "155 : Trois Cornes De Vendee",
219 "156 : Poivre d'Ane",
220 "157 : Caciocavallo",
221 "158 : Tupi",
222 "159 : Kashta",
223 "160 : Curworthy",
224 "161 : Bakers",
225 "162 : Toma",
226 "163 : Chevrotin des Aravis",
227 "164 : Friesla",
228 "165 : Sweet Style Swiss",
229 "166 : Bocconcini",
230 "167 : Alverca",
231 "168 : Gastanberra",
232 "169 : Trou du Cru",
233 "170 : Buchette d'Anjou",
234 "171 : Barry's Bay Cheddar",
235 "172 : Chabichou",
236 "173 : Galette Lyonnaise",
237 "174 : Tomme des Chouans",
238 "175 : Meyer Vintage Gouda",
239 "176 : Edelpilz",
240 "177 : Capricorn Goat",
241 "178 : Colby",
242 "179 : Macconais",
243 "180 : Port Nicholson",
244 "181 : Chaumes",
245 "182 : Castellano",
246 "183 : Reggianito",
247 "184 : Fromage a Raclette",
248 "185 : Blue",
249 "186 : Lou Palou",
250 "187 : Golden Cross",
251 "188 : Four Herb Gouda",
252 "189 : Celtic Promise",
253 "190 : Pave d'Affinois",
254 "191 : Tomme Brulee",
255 "192 : Port-Salut",
256 "193 : Quercy Petit",
257 "194 : Gospel Green",
258 "195 : Queso Iberico",
259 "196 : Cottage Cheese (Australian)",
260 "197 : Dessertnyj Belyj",
261 "198 : Mascarpone Torta",
262 "199 : Tilsit",
263 "200 : Fribourgeois",
264 "201 : Sveciaost",
265 "202 : Cuajada",
266 "203 : Waimata Farmhouse Blue",
267 "204 : Wensleydale",
268 "205 : Panela",
269 "206 : Berkswell",
270 "207 : Curd",
271 "208 : Lebbene",
272 "209 : Queso del Tietar",
273 "210 : Shelburne Cheddar",
274 "211 : Cendre d'Olivet",
275 "212 : Blue Rathgore",
276 "213 : Mahon",
277 "214 : Cheddar",
278 "215 : Rigotte",
279 "216 : Ossau Fermier",
280 "217 : Cold Pack",
281 "218 : Mycella",
282 "219 : Taleggio",
283 "220 : Selles sur Cher",
284 "221 : Podhalanski",
285 "222 : Coeur de Chevre",
286 "223 : Camembert de Normandie",
287 "224 : La Vache Qui Rit",
288 "225 : Quartirolo Lombardo",
289 "226 : Havarti",
290 "227 : Dolcelatte",
291 "228 : Manchego",
292 "229 : String",
293 "230 : Fourme de Haute Loire",
294 "231 : Paneer",
295 "232 : Crowley",
296 "233 : Gubbeen",
297 "234 : Evora De L'Alentejo",
298 "235 : Woodside Cabecou",
299 "236 : Lancashire",
300 "237 : Airedale",
301 "238 : Ackawi",
302 "239 : Brillat-Savarin",
303 "240 : Olivet Cendre",
304 "241 : Anneau du Vic-Bilh",
305 "242 : Fresh Ricotta",
306 "243 : Sbrinz",
307 "244 : Stinking Bishop",
308 "245 : Chabichou du Poitou",
309 "246 : Delice des Fiouves",
310 "247 : Briquette du Forez",
311 "248 : Yorkshire Blue",
312 "249 : Plateau de Herve",
313 "250 : Isle of Mull",
314 "251 : Tyn Grug",
315 "252 : Lavistown",
316 "253 : Requeson",
317 "254 : Cotherstone",
318 "255 : Somerset Brie",
319 "256 : Xynotyro",
320 "257 : Bel Paese",
321 "258 : Mozzarella Rolls",
322 "259 : Saint-Nectaire",
323 "260 : Sottocenare al Tartufo",
324 "261 : Basket Cheese",
325 "262 : Llanglofan Farmhouse",
326 "263 : Menonita",
327 "264 : Fresh Mozzarella",
328 "265 : Samso",
329 "266 : Castigliano",
330 "267 : Metton (Cancoillotte)",
331 "268 : Baladi",
332 "269 : Schabzieger",
333 "270 : Vasterbottenost",
334 "271 : Crema Agria",
335 "272 : Limburger",
336 "273 : Dorset Blue Vinney",
337 "274 : Doppelrhamstufel",
338 "275 : Gjetost",
339 "276 : Vendomois",
340 "277 : Allgauer Emmentaler",
341 "278 : Pont l'Eveque",
342 "279 : Geitost",
343 "280 : Knockalara",
344 "281 : Breakfast Cheese",
345 "282 : Northumberland",
346 "283 : Telemea",
347 "284 : Gornyaltajski",
348 "285 : Greuilh",
349 "286 : Ricotta (Australian)",
350 "287 : Le Brin",
351 "288 : Emental Grand Cru",
352 "289 : Mamirolle",
353 "290 : Brin d' Amour",
354 "291 : Petit Morin",
355 "292 : St. Agur Blue Cheese",
356 "293 : L'Aveyronnais",
357 "294 : Grana",
358 "295 : Devon Blue",
359 "296 : Grataron d' Areches",
360 "297 : Esbareich",
361 "298 : Parmesan (Parmigiano)",
362 "299 : Meira",
363 "300 : Frying Cheese",
364 "301 : Royalp Tilsit",
365 "302 : Laguiole",
366 "303 : Sardo Egyptian",
367 "304 : Olivet au Foin",
368 "305 : Pas de l'Escalette",
369 "306 : Tasmania Highland Chevre Log",
370 "307 : Haloumi-Style Cheese",
371 "308 : Loddiswell Avondale",
372 "309 : Nantais",
373 "310 : Herrgardsost",
374 "311 : Lajta",
375 "312 : Kenafa",
376 "313 : Cairnsmore",
377 "314 : Roule",
378 "315 : Emmental",
379 "316 : Brie de Melun",
380 "317 : Hereford Hop",
381 "318 : Jarlsberg",
382 "319 : Cure Nantais",
383 "320 : Herriot Farmhouse",
384 "321 : Tala",
385 "322 : Reblochon",
386 "323 : Mine-Gabhar",
387 "324 : Croghan",
388 "325 : Bouyssou",
389 "326 : Wellington",
390 "327 : Tete de Moine",
391 "328 : Valencay",
392 "329 : Passendale",
393 "330 : Blarney",
394 "331 : Grabetto",
395 "332 : Saga",
396 "333 : Cabecou",
397 "334 : Margotin",
398 "335 : Taupiniere",
399 "336 : Ricotta",
400 "337 : Bruder Basil",
401 "338 : Serra da Estrela",
402 "339 : Gris de Lille",
403 "340 : Fourme d' Ambert",
404 "341 : Cream Cheese",
405 "342 : Guerbigny",
406 "343 : Manouri",
407 "344 : Adelost",
408 "345 : Saanenkaese",
409 "346 : Castelmagno",
410 "347 : Stilton",
411 "348 : Graviera",
412 "349 : Mihalic Peynir",
413 "350 : Mozzarella",
414 "351 : Parmigiano Reggiano",
415 "352 : Brin d'Amour",
416 "353 : Kernhem",
417 "354 : Lincolnshire Poacher",
418 "355 : Queso Quesadilla",
419 "356 : Timboon Brie",
420 "357 : Kefalotyri",
421 "358 : Oxford Blue",
422 "359 : Zanetti Grana Padano",
423 "360 : Epoisses de Bourgogne",
424 "361 : Nokkelost",
425 "362 : Aragon",
426 "363 : Chontaleno",
427 "364 : Fougerus",
428 "365 : Cachaille",
429 "366 : Fin-de-Siecle",
430 "367 : Pecorino",
431 "368 : Hushallsost",
432 "369 : Tomme de Romans",
433 "370 : Cathelain",
434 "371 : Crowdie",
435 "372 : Queso Para Frier",
436 "373 : Olivet Bleu",
437 "374 : P'tit Berrichon",
438 "375 : Testouri",
439 "376 : Queso Fresco",
440 "377 : Gaperon a l'Ail",
441 "378 : Cotija",
442 "379 : Figue",
443 "380 : Lappi",
444 "381 : Richelieu",
445 "382 : Folded",
446 "383 : Fleur du Maquis",
447 "384 : Kikorangi",
448 "385 : Calenzana",
449 "386 : Durrus",
450 "387 : Maroilles",
451 "388 : Selva",
452 "389 : Creme Fraiche",
453 "390 : King River Gold",
454 "391 : Teifi",
455 "392 : Gowrie",
456 "393 : Ridder",
457 "394 : Babybel",
458 "395 : Filetta",
459 "396 : Fresh Truffles",
460 "397 : Caboc",
461 "398 : Gloucester",
462 "399 : Petit-Suisse",
463 "400 : Pressato",
464 "401 : Boule Du Roves",
465 "402 : Jermi Tortes",
466 "403 : Burgos",
467 "404 : Manur",
468 "405 : Brin",
469 "406 : Chabis de Gatine",
470 "407 : Fontal",
471 "408 : Abertam",
472 "409 : Cambazola",
473 "410 : Raclette",
474 "411 : Bath Cheese",
475 "412 : Vulscombe",
476 "413 : Washed Rind Cheese (Australian)",
477 "414 : Coulommiers",
478 "415 : Esrom",
479 "416 : Plymouth Cheese",
480 "417 : Torta del Casar",
481 "418 : Munster",
482 "419 : American Cheese",
483 "420 : Salers",
484 "421 : Orla",
485 "422 : Tamie",
486 "423 : Avaxtskyr",
487 "424 : Kugelkase",
488 "425 : Grafton Village Cheddar",
489 "426 : Civray",
490 "427 : Lingot Saint Bousquet d'Orb",
491 "428 : Butte",
492 "429 : Etorki",
493 "430 : Brie de Meaux",
494 "431 : Le Fium Orbo",
495 "432 : Penbryn",
496 "433 : Heidi Gruyere",
497 "434 : Braudostur",
498 "435 : Edam",
499 "436 : Ardi Gasna",
500 "437 : Menallack Farmhouse",
501 "438 : Laruns",
502 "439 : Wigmore",
503 "440 : Corleggy",
504 "441 : Tyning",
505 "442 : Boursault",
506 "443 : Galloway Goat's Milk Gems",
507 "444 : Fresh Jack",
508 "445 : Double Gloucester",
509 "446 : Rustinu",
510 "447 : Pecorino in Walnut Leaves",
511 "448 : Danbo",
512 "449 : Flower Marie",
513 "450 : Zamorano",
514 "451 : Roquefort",
515 "452 : Rocamadour",
516 "453 : Bocconcini (Australian)",
517 "454 : Prastost",
518 "455 : Brebis du Lochois",
519 "456 : Longhorn",
520 "457 : Mini Baby Bells",
521 "458 : Goutu",
522 "459 : Mothais a la Feuille",
523 "460 : Friesian",
524 "461 : Crayeux de Roncq",
525 "462 : Olde York",
526 "463 : Morbier Cru de Montagne",
527 "464 : Halloumi",
528 "465 : Prince-Jean",
529 "466 : Explorateur",
530 "467 : Beenleigh Blue",
531 "468 : Marble Cheddar",
532 "469 : Garrotxa",
533 "470 : Blue Vein (Australian)",
534 "471 : Asadero",
535 "472 : Sonoma Jack",
536 "473 : Soumaintrain",
537 "474 : Tronchon",
538 "475 : Canestrato",
539 "476 : Quark (Australian)",
540 "477 : Monterey Jack Dry",
541 "478 : Naboulsi",
542 "479 : Patefine Fort",
543 "480 : Bandal",
544 "481 : Fromage Frais",
545 "482 : Little Rydings",
546 "483 : Crottin du Chavignol",
547 "484 : Vignotte",
548 "485 : Serat",
549 "486 : Gabriel",
550 "487 : Processed Cheddar",
551 "488 : Rubens",
552 "489 : Polkolbin",
553 "490 : Finn",
554 "491 : Mascarpone",
555 "492 : Frinault",
556 "493 : Texas Goat Cheese",
557 "494 : Caerphilly",
558 "495 : Jubilee Blue",
559 "496 : Smoked Gouda",
560 "497 : Baylough",
561 "498 : Tourmalet",
562 "499 : Pave d'Auge",
563 "500 : Finlandia Swiss",
564 "501 : Dunsyre Blue",
565 "502 : Lou Pevre",
566 "503 : Remedou",
567 "504 : Pyengana Cheddar",
568 "505 : Abbaye de Belloc",
569 "506 : Cashel Blue",
570 "507 : Bergader",
571 "508 : Gratte-Paille",
572 "509 : Gippsland Blue",
573 "510 : Zanetti Parmigiano Reggiano",
574 "511 : Hipi Iti",
575 "512 : Raschera",
576 "513 : Venaco",
577 "514 : Mascarpone (Australian)",
578 "515 : Pouligny-Saint-Pierre",
579 "516 : Kervella Affine",
580 "517 : Lyonnais",
581 "518 : Dry Jack",
582 "519 : Pannerone",
583 "520 : Pelardon des Corbieres",
584 "521 : Mixte",
585 "522 : Loch Arthur Farmhouse",
586 "523 : Whitestone Farmhouse",
587 "524 : Iberico",
588 "525 : Meredith Blue",
589 "526 : Cabrales",
590 "527 : Vieux Corse",
591 "528 : Montasio",
592 "529 : Cheshire",
593 "530 : Baby Swiss",
594 "531 : Blue Vein Cheeses",
595 "532 : Red Leicester",
596 "533 : Neufchatel",
597 "534 : Coolea",
598 "535 : Swiss",
599 "536 : Waterloo",
600 "537 : Crescenza",
601 "538 : Buffalo",
602 "539 : Morbier",
603 "540 : Duddleswell",
604 "541 : Queso Blanco",
605 "542 : Xanadu",
606 "543 : Marbled Cheeses",
607 "544 : Halloumy (Australian)",
608 "545 : Ricotta Salata",
609 "546 : Tommes",
610 "547 : Balaton",
611 "548 : Mascares",
612 "549 : Piora",
613 "550 : Fruit Cream Cheese",
614 "551 : Queso Blanco con Frutas --Pina y Mango",
615 "552 : Maredsous",
616 "553 : Truffe",
617 "554 : Butterkase",
618 "555 : Pourly",
619 "556 : Anthoriro",
620 "557 : Juustoleipa",
621 "558 : Pithtviers au Foin",
622 "559 : San Simon",
623 "560 : Briquette de Brebis",
624 "561 : Ulloa",
625 "562 : Ragusano",
626 "563 : Mondseer",
627 "564 : Picos de Europa",
628 "565 : Formaggio di capra",
629 "566 : Brinza (Burduf Brinza)",
630 "567 : Boeren Leidenkaas",
631 "568 : Siraz",
632 "569 : Dutch Mimolette (Commissiekaas)",
633 "570 : La Taupiniere",
634 "571 : Sardo",
635 "572 : Yarra Valley Pyramid",
636 "573 : Malvern",
637 "574 : Monterey Jack",
638 "575 : Aisy Cendre",
639 "576 : Cantal",
640 "577 : Sussex Slipcote",
641 "578 : Capriole Banon",
642 "579 : Abondance",
643 "580 : Pave du Berry",
644 "581 : Brie",
645 "582 : Asiago",
646 "583 : Denhany Dorset Drum",
647 "584 : Banon",
648 "585 : Fontainebleau",
649 "586 : Chevres",
650 "587 : Quatre-Vents",
651 "588 : Syrian (Armenian String)",
652 "589 : Touree de L'Aubier",
653 "590 : Vacherin-Fribourgeois",
654 "591 : Basing",
655 "592 : Daralagjazsky",
656 "593 : Sage Derby",
657 "594 : Folded cheese with mint",
658 "595 : Flor de Guia",
659 "596 : Comte",
660 "597 : Milleens",
661 "598 : Double Worcester",
662 "599 : Pelardon des Cevennes",
663 "600 : Idiazabal",
664 "601 : Sharpam",
665 "602 : Mesost",
666 "603 : Sraffordshire Organic",
667 "604 : Grand Vatel",
668 "605 : Cheddar Clothbound",
669 "606 : Jibneh Arabieh",
670 "607 : Charolais",
671 "608 : Picodon de Chevre",
672 "609 : Brusselae Kaas (Fromage de Bruxelles)",
673 "610 : Devon Garland",
674 "611 : Emlett",
675 "612 : Dunlop",
676 "613 : Beer Cheese",
677 "614 : Cwmtawe Pecorino",
678 "615 : Tymsboro",
679 "616 : Romano",
680 "617 : Oaxaca",
681 "618 : Derby",
682 "619 : Tomme d'Abondance",
683 "620 : Livarot",
684 "621 : Queso de Murcia",
685 "622 : Molbo",
686 "623 : Broccio",
687 "624 : Il Boschetto al Tartufo",
688 "625 : Airag",
689 "626 : Bougon",
690 "627 : Roncal",
691 "628 : Penamellera",
692 "629 : Turunmaa",
693 "630 : Affidelice au Chablis",
694 "631 : Sap Sago",
695 "632 : Queso Media Luna",
696 "633 : Button (Innes)",
697 "634 : Brousse du Rove",
698 "635 : Pave de Chirac",
699 "636 : Ambert",
700 "637 : Coquetdale",
701 "638 : Armenian String",
702 "639 : Danish Fontina",
703 "640 : White Stilton",
704 "641 : Pencarreg",
705 "642 : Bleu d'Auvergne",
706 "643 : Crema Mexicana",
707 "644 : Le Lacandou",
708 "645 : Bergere Bleue",
709 "646 : Carre de l'Est",
710 "647 : Beaufort",
711 "648 : Cottage Cheese",
712 "649 : Quark",
713 "650 : Oschtjepka",
714 "651 : Boursin",
715 "652 : Tibet",
716 "653 : Tomme de Savoie",
717 "654 : Palet de Babligny",
718 };
719 }
Demo layout code:
