Проблема с расширенным линейным описанием Alphabet Bar

#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, но все равно получил исключение. Что не так?