开发者

Alphabet Bar extended linearlayout problem

I'm trying to get an Android Alphabet positioning bar to work following an old example provided by Josh Guilfoyle:

AlphabetBarListView <- original project and screen capture can be found here

I was able to debug the code to get the alphabet bar itself to display using

setContentView(new AlphabetBar(this));

but I can't figure out how to display the alphabet bar over a listview under Android 2.1 as shown in the photo. I've created a really small project to try and get it to work, but I'm obviously doing something wrong. Thanks guys! I really appreciate the help.

HelloWorld.java

package com.demo.helloworld;

import android.app.Activity;
import android.os.Bundle;
import and开发者_StackOverflow社区roid.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 (under drawable folder)

<?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>


Okay, I figured this out.

(1) Change the layout from LinearLayout to RelativeLayout.

(2) Remove Map inflateParams from the AlphabetBar constructor.

And Viola!! It works! LOL

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜