如何在listview中添加快速滚动和字母部分索引

时间:2012-09-25 10:57:21

标签: android android-layout android-intent android-emulator android-ndk

详细说明,我正在寻找一个与下图完全相同的例子。我在这个链接https://github.com/woozzu/IndexableListView中得到了一个很好的例子。它的工作正常我的要求。但是当我实现我的项目时,它在列表视图中显示错误。下面是我的代码PLZ帮帮我。我是这个话题的新手。提前谢谢!

寻找:

screenshot of desired UI
这是我的代码下面plz说我的错误..

MainActivity .java

public class MainActivity extends Activity implements     SearchView.OnQueryTextListener,SearchView.OnCloseListener {

private ListView listView;
private SearchView search;
EfficientAdapter objectAdapter;
EfficientAdapter2 objectAdapter1;
int textlength=0;
private CheckBox checkStat, checkRoutine, checkTat;
 private GestureDetector mGestureDetector;
private ArrayList<CountriesList> elements;


@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
   setContentView(R.layout.homempleb);
   Log.i("scan"," txtScanResult ");


//Arrays.sort(CountriesList.name);
ActionItem nextItem     = new ActionItem(); 
final QuickAction quickAction = new QuickAction(this, QuickAction.VERTICAL);
quickAction.addActionItem(nextItem);
quickAction.setOnDismissListener(new QuickAction.OnDismissListener() {          
    @Override
    public void onDismiss() {
        Toast.makeText(getApplicationContext(), "Dismissed", Toast.LENGTH_SHORT).show();
    }
});


search = (SearchView) findViewById(R.id.searchView1);
search.setIconifiedByDefault(false);    
search.setOnQueryTextListener(this);
search.setOnCloseListener(this);
search.setOnClickListener(new View.OnClickListener() {
    public void onClick(View v) {
        quickAction.show(v);
    }
});
checkStat  =  (CheckBox) findViewById(R.id.checkBoxStat);
checkRoutine  =  (CheckBox) findViewById(R.id.checkBoxRoutine);
checkTat  =  (CheckBox) findViewById(R.id.checkBoxTat);
checkStat.setOnClickListener(new OnClickListener() {             
      @Override
      public void onClick(View v) {                  
          if (((CheckBox) v).isChecked()) {
              checkStat.setChecked(true);
              Toast.makeText(MainActivity.this, "STAT", Toast.LENGTH_SHORT).show();
              checkRoutine.setChecked(false);
              checkTat.setChecked(false);                 
                } 
      }
    });
checkRoutine.setOnClickListener(new OnClickListener() {          
      @Override
      public void onClick(View v) {                  
          if (((CheckBox) v).isChecked()) {
              checkRoutine.setChecked(true);
              Toast.makeText(MainActivity.this, "ROUTINE", Toast.LENGTH_SHORT).show();
              checkStat.setChecked(false);
              checkTat.setChecked(false);                 
                } 
      }
    });
checkTat.setOnClickListener(new OnClickListener() {          
      @Override
      public void onClick(View v) {                  
          if (((CheckBox) v).isChecked()) {
              checkTat.setChecked(true);
              Toast.makeText(MainActivity.this, "TAT Effeciency", Toast.LENGTH_SHORT).show();
              checkRoutine.setChecked(false);
              checkStat.setChecked(false);                
                } 
      }
    });




listView = (ListView) findViewById(R.id.homelistView);
listView.setTextFilterEnabled(true);
listView.setFastScrollEnabled(true);  
objectAdapter = new EfficientAdapter(this, elements );
listView.setAdapter(objectAdapter);

Button refreshButton= (Button)findViewById(R.id.refreshButton);
 refreshButton.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        objectAdapter1 = new EfficientAdapter2(MainActivity.this);
//       objectAdapter = new EfficientAdapter(MainActivity.this);// adapter with new data
       listView.setAdapter(objectAdapter1);

       Log.i("notifyDataSetChanged", "data updated");
       objectAdapter1.notifyDataSetChanged();

    }
});  

}

@Override
public boolean onClose() {
    return false;
}

@Override
public boolean onQueryTextChange(String newText) {
    return false;
}

@Override
public boolean onQueryTextSubmit(String query) {
    return false;
}
}

EfficientAdapter.java

  public class EfficientAdapter extends BaseAdapter implements SectionIndexer {

private AlphabetIndexer alphaIndexer;

private String mSections = "#ABCDEFGHIJKLMNOPQRSTUVWXYZ";

   private LayoutInflater mInflater;
    private Context context;

  public EfficientAdapter(Context context, ArrayList<CountriesList> elements) {
mInflater = LayoutInflater.from(context);



this.context=context;

   }


public int getCount() {
return CountriesList.name.length;
    }

       public Object getItem(int position) {

return position;
     }

           public long getItemId(int position) {
return position;
         }

      public View getView(int position, View convertView, ViewGroup parent) {
     ViewHolder holder;
   if (convertView == null) {
    convertView = mInflater.inflate(R.layout.homemplebrowview, null);
    holder = new ViewHolder();
    holder.text1 = (TextView) convertView
            .findViewById(R.id.name);
    holder.text2 = (TextView) convertView
            .findViewById(R.id.mrn);
    holder.text3 = (TextView) convertView
            .findViewById(R.id.date);
    holder.text4 = (TextView) convertView
            .findViewById(R.id.age);
    holder.text5 = (TextView) convertView
            .findViewById(R.id.gender);
    holder.text6 = (TextView) convertView
            .findViewById(R.id.wardno);
    holder.text7 = (TextView) convertView
            .findViewById(R.id.roomno);
    holder.text8 = (TextView) convertView
            .findViewById(R.id.bedno);                  
    holder.btnList = (Button)convertView.findViewById(R.id.listbutton);
         //   holder.btnList.setOnClickListener(this);

    holder.btnList.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {                       
            Intent next=new Intent(context, SeviceDetails.class);
            context.startActivity(next);
        }
    });


    convertView.setTag(holder);
} else {
    holder = (ViewHolder) convertView.getTag();
}

holder.text1.setText(CountriesList.name[position]);
holder.text2.setText(CountriesList.mrn[position]);
holder.text3.setText(CountriesList.actualstart[position]);
holder.text4.setText(CountriesList.age[position]);
holder.text5.setText(CountriesList.gender[position]);
holder.text6.setText(CountriesList.wardNo[position]);
holder.text7.setText(CountriesList.roomNo[position]);
holder.text8.setText(CountriesList.bedNo[position]);

return convertView;
      }


    static class ViewHolder {
public Button btnList;
public TextView text8;
public TextView text7;
public TextView text6;
public TextView text5;
public TextView text4;
public TextView text1;
public TextView text2;
public TextView text3;
     }

         @Override
    public void notifyDataSetChanged()
      {
    super.notifyDataSetChanged();
         }


        @Override
          public int getPositionForSection(int section) {
// If there is no item for current section, previous section will be selected
for (int i = section; i >= 0; i--) {
    for (int j = 0; j < getCount(); j++) {
        if (i == 0) {
            // For numeric section
            for (int k = 0; k <= 9; k++) {
            //  if (StringMatcher.match(String.valueOf(getItem(j).charAt(0)), String.valueOf(k)))
                    return j;
            }
        } else {
        //  if (StringMatcher.match(String.valueOf(getItem(j).charAt(0)), String.valueOf(mSections.charAt(i))))
                return j;
        }
    }
}
return 0;
    }


   @Override
           public int getSectionForPosition(int position) {
return 0;
      }


         @Override
   public Object[] getSections() {
String[] sections = new String[mSections.length()];
for (int i = 0; i < mSections.length(); i++)
    sections[i] = String.valueOf(mSections.charAt(i));
return sections;
      }

      }

IndexableListView.java

  public class IndexableListView extends ListView {

private boolean mIsFastScrollEnabled = false;
private IndexScroller mScroller = null;
private GestureDetector mGestureDetector = null;

public IndexableListView(Context context) {
    super(context);
}

public IndexableListView(Context context, AttributeSet attrs) {
    super(context, attrs);
}

public IndexableListView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
}

@Override
public boolean isFastScrollEnabled() {
    return mIsFastScrollEnabled;
}

@Override
public void setFastScrollEnabled(boolean enabled) {
    mIsFastScrollEnabled = enabled;
    if (mIsFastScrollEnabled) {
        if (mScroller == null)
            mScroller = new IndexScroller(getContext(), this);
    } else {
        if (mScroller != null) {
            mScroller.hide();
            mScroller = null;
        }
    }
}

@Override
public void draw(Canvas canvas) {
    super.draw(canvas);

    // Overlay index bar
    if (mScroller != null)
        mScroller.draw(canvas);
}

@Override
public boolean onTouchEvent(MotionEvent ev) {
    // Intercept ListView's touch event
    if (mScroller != null && mScroller.onTouchEvent(ev))
        return true;

    if (mGestureDetector == null) {
        mGestureDetector = new GestureDetector(getContext(), new GestureDetector.SimpleOnGestureListener() {

            @Override
            public boolean onFling(MotionEvent e1, MotionEvent e2,
                    float velocityX, float velocityY) {
                // If fling happens, index bar shows
                mScroller.show();
                return super.onFling(e1, e2, velocityX, velocityY);
            }

        });
    }
    mGestureDetector.onTouchEvent(ev);

    return super.onTouchEvent(ev);
}

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
    return true;
}

@Override
public void setAdapter(ListAdapter adapter) {
    super.setAdapter(adapter);
    if (mScroller != null)
        mScroller.setAdapter(adapter);
}

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
    super.onSizeChanged(w, h, oldw, oldh);
    if (mScroller != null)
        mScroller.onSizeChanged(w, h, oldw, oldh);
}

}

StringMatcher.java

 public class StringMatcher {


public static boolean match(String value, String keyword) {
    if (value == null || keyword == null)
        return false;
    if (keyword.length() > value.length())
        return false;

    int i = 0, j = 0;
    do {
        if (isKorean(value.charAt(i)) && isInitialSound(keyword.charAt(j))) {
        } else {
            if (keyword.charAt(j) == value.charAt(i)) {
                i++;
                j++;
            } else if (j > 0)
                break;
            else
                i++;
        }
    } while (i < value.length() && j < keyword.length());

    return (j == keyword.length())? true : false;
}

private static boolean isKorean(char c) {
    return false;
}

private static boolean isInitialSound(char c) {
    return false;
}

}

IndexScroller.java

public class IndexScroller {



private static final int STATE_HIDDEN = 0;
private static final int STATE_SHOWING = 1;
private static final int STATE_SHOWN = 2;
private static final int STATE_HIDING = 3;

public IndexScroller(Context context, ListView lv) {
    mDensity = context.getResources().getDisplayMetrics().density;
    mScaledDensity = context.getResources().getDisplayMetrics().scaledDensity;
    mListView = lv;
    setAdapter(mListView.getAdapter());

    mIndexbarWidth = 20 * mDensity;
    mIndexbarMargin = 10 * mDensity;
    mPreviewPadding = 5 * mDensity;
}

public void draw(Canvas canvas) {
    if (mState == STATE_HIDDEN)
        return;

    // mAlphaRate determines the rate of opacity
    Paint indexbarPaint = new Paint();
    indexbarPaint.setColor(Color.BLACK);
    indexbarPaint.setAlpha((int) (64 * mAlphaRate));
    indexbarPaint.setAntiAlias(true);
    canvas.drawRoundRect(mIndexbarRect, 5 * mDensity, 5 * mDensity, indexbarPaint);

    if (mSections != null && mSections.length > 0) {
        // Preview is shown when mCurrentSection is set
        if (mCurrentSection >= 0) {
            Paint previewPaint = new Paint();
            previewPaint.setColor(Color.BLACK);
            previewPaint.setAlpha(96);
            previewPaint.setAntiAlias(true);
            previewPaint.setShadowLayer(3, 0, 0, Color.argb(64, 0, 0, 0));

            Paint previewTextPaint = new Paint();
            previewTextPaint.setColor(Color.WHITE);
            previewTextPaint.setAntiAlias(true);
            previewTextPaint.setTextSize(50 * mScaledDensity);

            float previewTextWidth = previewTextPaint.measureText(mSections[mCurrentSection]);
            float previewSize = 2 * mPreviewPadding + previewTextPaint.descent() - previewTextPaint.ascent();
            RectF previewRect = new RectF((mListViewWidth - previewSize) / 2
                    , (mListViewHeight - previewSize) / 2
                    , (mListViewWidth - previewSize) / 2 + previewSize
                    , (mListViewHeight - previewSize) / 2 + previewSize);

            canvas.drawRoundRect(previewRect, 5 * mDensity, 5 * mDensity, previewPaint);
            canvas.drawText(mSections[mCurrentSection], previewRect.left + (previewSize - previewTextWidth) / 2 - 1
                    , previewRect.top + mPreviewPadding - previewTextPaint.ascent() + 1, previewTextPaint);
        }

        Paint indexPaint = new Paint();
        indexPaint.setColor(Color.WHITE);
        indexPaint.setAlpha((int) (255 * mAlphaRate));
        indexPaint.setAntiAlias(true);
        indexPaint.setTextSize(12 * mScaledDensity);

        float sectionHeight = (mIndexbarRect.height() - 2 * mIndexbarMargin) / mSections.length;
        float paddingTop = (sectionHeight - (indexPaint.descent() - indexPaint.ascent())) / 2;
        for (int i = 0; i < mSections.length; i++) {
            float paddingLeft = (mIndexbarWidth - indexPaint.measureText(mSections[i])) / 2;
            canvas.drawText(mSections[i], mIndexbarRect.left + paddingLeft
                    , mIndexbarRect.top + mIndexbarMargin + sectionHeight * i + paddingTop - indexPaint.ascent(), indexPaint);
        }
    }
}

public boolean onTouchEvent(MotionEvent ev) {
    switch (ev.getAction()) {
    case MotionEvent.ACTION_DOWN:
        // If down event occurs inside index bar region, start indexing
        if (mState != STATE_HIDDEN && contains(ev.getX(), ev.getY())) {
            setState(STATE_SHOWN);

            // It demonstrates that the motion event started from index bar
            mIsIndexing = true;
            // Determine which section the point is in, and move the list to that section
            mCurrentSection = getSectionByPoint(ev.getY());
            mListView.setSelection(mIndexer.getPositionForSection(mCurrentSection));
            return true;
        }
        break;
    case MotionEvent.ACTION_MOVE:
        if (mIsIndexing) {
            // If this event moves inside index bar
            if (contains(ev.getX(), ev.getY())) {
                // Determine which section the point is in, and move the list to that section
                mCurrentSection = getSectionByPoint(ev.getY());
                mListView.setSelection(mIndexer.getPositionForSection(mCurrentSection));
            }
            return true;
        }
        break;
    case MotionEvent.ACTION_UP:
        if (mIsIndexing) {
            mIsIndexing = false;
            mCurrentSection = -1;
        }
        if (mState == STATE_SHOWN)
            setState(STATE_HIDING);
        break;
    }
    return false;
}

public void onSizeChanged(int w, int h, int oldw, int oldh) {
    mListViewWidth = w;
    mListViewHeight = h;
    mIndexbarRect = new RectF(w - mIndexbarMargin - mIndexbarWidth
            , mIndexbarMargin
            , w - mIndexbarMargin
            , h - mIndexbarMargin);
}

public void show() {
    if (mState == STATE_HIDDEN)
        setState(STATE_SHOWING);
    else if (mState == STATE_HIDING)
        setState(STATE_HIDING);
}

public void hide() {
    if (mState == STATE_SHOWN)
        setState(STATE_HIDING);
}

public void setAdapter(Adapter adapter) {
    if (adapter instanceof SectionIndexer) {
        mIndexer = (SectionIndexer) adapter;
        mSections = (String[]) mIndexer.getSections();
    }
}

private void setState(int state) {
    if (state < STATE_HIDDEN || state > STATE_HIDING)
        return;

    mState = state;
    switch (mState) {
    case STATE_HIDDEN:
        // Cancel any fade effect
        mHandler.removeMessages(0);
        break;
    case STATE_SHOWING:
        // Start to fade in
        mAlphaRate = 0;
        fade(0);
        break;
    case STATE_SHOWN:
        // Cancel any fade effect
        mHandler.removeMessages(0);
        break;
    case STATE_HIDING:
        // Start to fade out after three seconds
        mAlphaRate = 1;
        fade(3000);
        break;
    }
}

private boolean contains(float x, float y) {
    // Determine if the point is in index bar region, which includes the right margin of the bar
    return (x >= mIndexbarRect.left && y >= mIndexbarRect.top && y <= mIndexbarRect.top + mIndexbarRect.height());
}

private int getSectionByPoint(float y) {
    if (mSections == null || mSections.length == 0)
        return 0;
    if (y < mIndexbarRect.top + mIndexbarMargin)
        return 0;
    if (y >= mIndexbarRect.top + mIndexbarRect.height() - mIndexbarMargin)
        return mSections.length - 1;
    return (int) ((y - mIndexbarRect.top - mIndexbarMargin) / ((mIndexbarRect.height() - 2 * mIndexbarMargin) / mSections.length));
}

private void fade(long delay) {
    mHandler.removeMessages(0);
    mHandler.sendEmptyMessageAtTime(0, SystemClock.uptimeMillis() + delay);
}

private Handler mHandler = new Handler() {

    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);

        switch (mState) {
        case STATE_SHOWING:
            // Fade in effect
            mAlphaRate += (1 - mAlphaRate) * 0.2;
            if (mAlphaRate > 0.9) {
                mAlphaRate = 1;
                setState(STATE_SHOWN);
            }

            mListView.invalidate();
            fade(10);
            break;
        case STATE_SHOWN:
            // If no action, hide automatically
            setState(STATE_HIDING);
            break;
        case STATE_HIDING:
            // Fade out effect
            mAlphaRate -= mAlphaRate * 0.2;
            if (mAlphaRate < 0.1) {
                mAlphaRate = 0;
                setState(STATE_HIDDEN);
            }

            mListView.invalidate();
            fade(10);
            break;
        }
    }

};
 }

如果我添加它,它将在mainactivity中运行代码       listView =(ListView)findViewById(R.id.homelistView);

2 个答案:

答案 0 :(得分:4)

您使用的是自定义ListView类,com.woozzu.android.widget.IndexableListView 你必须将布局文件中的“ListView”替换为“com.woozzu.android.widget.IndexableListView”

将布局更改为:

 <?xml version="1.0" encoding="utf-8"?>
        <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:background="#ff3344"
        android:layout_height="fill_parent" >



            <LinearLayout
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_alignParentBottom="true"
                android:background="#ffffff"     
                android:layout_alignTop="@+id/scrollView1"
                android:layout_toRightOf="@+id/scrollView1" >           


                <com.woozzu.android.widget.IndexableListView
                    android:id="@+id/homelistView"
                    android:layout_width="0dip"
                    android:layout_height="fill_parent"
                    android:layout_weight="1.04"
                    android:dividerHeight="0dip" >

                </com.woozzu.android.widget.IndexableListView>

            </LinearLayout>

        </RelativeLayout>

        </LinearLayout>

答案 1 :(得分:2)

@Anis建议的解决方案是我找到的唯一可行解决方案。除此之外,如果您希望单击侦听器到列表视图项目上的组件,则必须更新此处提到的代码,https://github.com/denley/IndexableListView/commit/18210a54487ba079bb332fafec709e2de26883db