#android #alphabet
#Android #алфавит
Вопрос:
Я пытаюсь заставить панель позиционирования алфавита Android работать, следуя старому примеру, предоставленному Джошем Гилфойлом:
AlphabetBarListView <- оригинальный проект и снимок экрана можно найти здесь
Я смог отладить код, чтобы заставить саму строку алфавита отображаться с помощью
setContentView(new AlphabetBar(this));
но я не могу понять, как отобразить строку алфавита поверх listview под Android 2.1, как показано на фотографии. Я создал действительно небольшой проект, чтобы попытаться заставить его работать, но я, очевидно, делаю что-то не так. Спасибо, ребята! Я действительно ценю помощь.
HelloWorld.java
package com.demo.helloworld;
import android.app.Activity;
import android.os.Bundle;
import android.widget.ListView;
public class HelloWorld extends Activity {
/** Called when the activity is first created. */
public AlphabetBar mAlphabetBar;
public ListView listView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
setContentView(new AlphabetBar(this));
listView = (ListView)findViewById(R.id.mylist);
mAlphabetBar = (AlphabetBar)findViewById(R.id.alphabet_bar);
}
}
AlphabetBar.java
package com.demo.helloworld;
import java.util.Map;
import android.content.Context;
import android.text.Layout.Alignment;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;
public class AlphabetBar extends LinearLayout
{
private static final String TAG = "AlphabetBar";
public AlphabetBar(Context context)
{
super(context);
init();
}
public AlphabetBar(Context context, AttributeSet attrs, Map inflateParams)
{
super(context, attrs);
init();
}
public void init()
{
setLayoutParams(new LinearLayout.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.FILL_PARENT));
/* Not strictly necessary since we override onLayout and onMeasure with
* our custom logic, but it seems like good form to do this just to
* show how we're arranging the children. */
setOrientation(VERTICAL);
char[] labels =
{
'#',
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
};
for (int i = 0; i < labels.length; i )
{
TextView label = new TextView(getContext());
label.setText(String.valueOf(labels[i]));
// label.setAlignment(Alignment.ALIGN_CENTER);
label.setGravity(Gravity.CENTER_VERTICAL);
label.setClickable(true);
label.setFocusable(true);
label.setOnClickListener(mLabelClicked);
addView(label, new LinearLayout.LayoutParams(
LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
}
}
private OnClickListener mLabelClicked = new OnClickListener()
{
public void onClick(View v)
{
if (mClickCallback != null)
mClickCallback.onClick(v);
}
};
private OnClickListener mClickCallback = null;
/**
* Set the click listener for alphabet labels.
*
* @param listener
* Click listener, or null to unset.
*/
public void setLabelClickListener(OnClickListener listener)
{
mClickCallback = listener;
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b)
{
super.onLayout(changed, l, t, r, b);
}
private void useDefaultBackground()
{
setBackgroundResource(R.drawable.alphabet_bar_bg);
}
@Override
protected void onMeasure(int wSpec, int hSpec)
{
Log.d(TAG, "onMeasure(" wSpec ", " hSpec ")");
if (getBackground() == null)
useDefaultBackground();
int count = getChildCount();
int hMode = MeasureSpec.getMode(hSpec);
int hSize = MeasureSpec.getSize(hSpec);
assert hMode == MeasureSpec.EXACTLY;
int maxWidth = 0;
int hSizeAdj = hSize - getPaddingTop() - getPaddingBottom();
float childHeight = hSizeAdj / count;
/* Calculate how many extra 1-pixel spaces we'll need in order to make
* childHeight align to integer heights. */
int variance = hSizeAdj - ((int)childHeight * count);
int paddingWidth = getPaddingLeft() getPaddingRight();
for (int i = 0; i < count; i )
{
TextView label = (TextView)getChildAt(i);
label.setTextSize(childHeight * 0.9F);
int thisHeight = (int)childHeight;
if (variance > 0)
{
thisHeight ;
variance--;
}
label.measure
(MeasureSpec.makeMeasureSpec(13, MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(thisHeight, MeasureSpec.EXACTLY));
maxWidth = Math.max(maxWidth, label.getMeasuredWidth());
}
maxWidth = paddingWidth;
setMeasuredDimension(resolveSize(maxWidth, wSpec), hSize);
}
}
alphabet_bar_bg.xml (в папке drawable)
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
type="rectangle">
<solid android:color="#20777777" />
<corners android:radius="8dip" />
</shape>
mail.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<ListView
android:id="@ id/mylist"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
<com.demo.helloworld.AlphabetBar
android:id="@ id/alphabet_bar"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_alignParentRight="true"
android:layout_marginRight="6dip"
android:layout_marginTop="14dip"
android:layout_marginBottom="14dip"
android:paddingTop="2dip"
android:paddingBottom="2dip"
android:paddingLeft="4dip"
android:paddingRight="4dip"
/>
</LinearLayout>
Ответ №1:
Хорошо, я разобрался с этим.
(1) Измените макет с LinearLayout на RelativeLayout.
(2) Удалите Map inflateParams из конструктора AlphabetBar.
И альт!! Это работает!лол
Комментарии:
1. Отлично! Вы можете принять свой собственный ответ, поставив галочку рядом со стрелками вверх / вниз.
2. Я копирую ваш код, меняю LinearLayout на RelativeLayout в main.xml и удалите Map inflateParams в конструкторе AlphabetBar, но все равно получил исключение. Что не так?