android拉到刷新listview

时间:2014-10-20 05:36:23

标签: android listview android-activity android-listview refresh

我从服务器检索一些数据并将它们填充到列表视图中。我想在listview中实现pull to refresh,但是我的应用程序出现了错误。我使用其他人编写的库来进行刷新功能。

这是我的代码:

public class MainActivity extends Activity {
ListView list;
TextView ver;
TextView name;
TextView api;
Button Btngetdata;
ArrayList<HashMap<String, String>> oslist = new ArrayList<HashMap<String, String>>();

//URL to get JSON Array
private static String url = "http://api.learn2crack.com/android/jsonos/";

//JSON Node Names 
private static final String TAG_OS = "android";
private static final String TAG_VER = "ver";
private static final String TAG_NAME = "name";
private static final String TAG_API = "api";

JSONArray android = null;




@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);
    oslist = new ArrayList<HashMap<String, String>>();
    ((PullToRefreshListView)list).setOnRefreshListener(new OnRefreshListener() {

        public void onRefresh() {
            // Do work to refresh the list here.
             new JSONParse().execute();
        }
    });
    Btngetdata = (Button)findViewById(R.id.getdata);
    Btngetdata.setOnClickListener(new View.OnClickListener() {

        //@Override
        public void onClick(View view) {
            new JSONParse().execute();



        }
    });



}



private class JSONParse extends AsyncTask<String, String, JSONObject> {
     private ProgressDialog pDialog;

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
         ver = (TextView)findViewById(R.id.vers);
         name = (TextView)findViewById(R.id.name);
         api = (TextView)findViewById(R.id.api);
        pDialog = new ProgressDialog(MainActivity.this);
        pDialog.setMessage("Getting Data ...");
        pDialog.setIndeterminate(false);
        pDialog.setCancelable(true);
        pDialog.show();




    }

    @Override
    protected JSONObject doInBackground(String... args) {

        JSONParser jParser = new JSONParser();

        // Getting JSON from URL
        JSONObject json = jParser.getJSONFromUrl(url);
        /* try {
             Thread.sleep(2000);
         } catch (InterruptedException e) {
             ;
         }*/
        return json;
    }
     @Override
     protected void onPostExecute(JSONObject json) {
         pDialog.dismiss();
         ((PullToRefreshListView) list).onRefreshComplete();

         try {
                // Getting JSON Array from URL
                android = json.getJSONArray(TAG_OS);
                for(int i = 0; i < android.length(); i++){
                JSONObject c = android.getJSONObject(i);

                // Storing  JSON item in a Variable
                String ver = c.getString(TAG_VER);
                String name = c.getString(TAG_NAME);
                String api = c.getString(TAG_API);




                // Adding value HashMap key => value


                HashMap<String, String> map = new HashMap<String, String>();

                map.put(TAG_VER, ver);
                map.put(TAG_NAME, name);
                map.put(TAG_API, api);

                oslist.add(map);
                list=(ListView)findViewById(R.id.list);





                ListAdapter adapter = new SimpleAdapter(MainActivity.this, oslist,
                        R.layout.list_v,
                        new String[] { TAG_VER,TAG_NAME, TAG_API }, new int[] {
                                R.id.vers,R.id.name, R.id.api});

                list.setAdapter(adapter);


                list.setOnItemClickListener(new AdapterView.OnItemClickListener() {

                    @Override
                    public void onItemClick(AdapterView<?> parent, View view,
                                            int position, long id) {
                       // Toast.makeText(MainActivity.this, "You Clicked at "+oslist.get(+position).get("name"), Toast.LENGTH_SHORT).show();
                         String namee = oslist.get(position).get("name");
                         Intent intent = new Intent(MainActivity.this, New.class);
                         intent.putExtra("key", namee);
                         startActivity(intent);
                    }
                });

                }
        } catch (JSONException e) {
            e.printStackTrace();
        }


     }
}

}

以下是刷新代码的提示:

public class PullToRefreshListView extends ListView implements OnScrollListener {

private static final int TAP_TO_REFRESH = 1;
private static final int PULL_TO_REFRESH = 2;
private static final int RELEASE_TO_REFRESH = 3;
private static final int REFRESHING = 4;

private static final String TAG = "PullToRefreshListView";

private OnRefreshListener mOnRefreshListener;

/**
 * Listener that will receive notifications every time the list scrolls.
 */
private OnScrollListener mOnScrollListener;
private LayoutInflater mInflater;

private RelativeLayout mRefreshView;
private TextView mRefreshViewText;
private ImageView mRefreshViewImage;
private ProgressBar mRefreshViewProgress;
private TextView mRefreshViewLastUpdated;

private int mCurrentScrollState;
private int mRefreshState;

private RotateAnimation mFlipAnimation;
private RotateAnimation mReverseFlipAnimation;

private int mRefreshViewHeight;
private int mRefreshOriginalTopPadding;
private int mLastMotionY;

private boolean mBounceHack;

public PullToRefreshListView(Context context) {
    super(context);
    init(context);
}

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

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

private void init(Context context) {
    // Load all of the animations we need in code rather than through XML
    mFlipAnimation = new RotateAnimation(0, -180,
            RotateAnimation.RELATIVE_TO_SELF, 0.5f,
            RotateAnimation.RELATIVE_TO_SELF, 0.5f);
    mFlipAnimation.setInterpolator(new LinearInterpolator());
    mFlipAnimation.setDuration(250);
    mFlipAnimation.setFillAfter(true);
    mReverseFlipAnimation = new RotateAnimation(-180, 0,
            RotateAnimation.RELATIVE_TO_SELF, 0.5f,
            RotateAnimation.RELATIVE_TO_SELF, 0.5f);
    mReverseFlipAnimation.setInterpolator(new LinearInterpolator());
    mReverseFlipAnimation.setDuration(250);
    mReverseFlipAnimation.setFillAfter(true);

    mInflater = (LayoutInflater) context.getSystemService(
            Context.LAYOUT_INFLATER_SERVICE);

    mRefreshView = (RelativeLayout) mInflater.inflate(
            R.layout.pull_to_refresh_header, this, false);
    mRefreshViewText =
        (TextView) mRefreshView.findViewById(R.id.pull_to_refresh_text);
    mRefreshViewImage =
        (ImageView) mRefreshView.findViewById(R.id.pull_to_refresh_image);
    mRefreshViewProgress =
        (ProgressBar) mRefreshView.findViewById(R.id.pull_to_refresh_progress);
    mRefreshViewLastUpdated =
        (TextView) mRefreshView.findViewById(R.id.pull_to_refresh_updated_at);

    mRefreshViewImage.setMinimumHeight(50);
    mRefreshView.setOnClickListener(new OnClickRefreshListener());
    mRefreshOriginalTopPadding = mRefreshView.getPaddingTop();

    mRefreshState = TAP_TO_REFRESH;

    addHeaderView(mRefreshView);

    super.setOnScrollListener(this);

    measureView(mRefreshView);
    mRefreshViewHeight = mRefreshView.getMeasuredHeight();
}

@Override
protected void onAttachedToWindow() {
    super.onAttachedToWindow();
    setSelection(1);
}

@Override
public void setAdapter(ListAdapter adapter) {
    super.setAdapter(adapter);
    setSelection(1);
}

/**
 * Set the listener that will receive notifications every time the list
 * scrolls.
 * 
 * @param l The scroll listener. 
 */
@Override
public void setOnScrollListener(AbsListView.OnScrollListener l) {
    mOnScrollListener = l;
}

/**
 * Register a callback to be invoked when this list should be refreshed.
 * 
 * @param onRefreshListener The callback to run.
 */
public void setOnRefreshListener(OnRefreshListener onRefreshListener) {
    mOnRefreshListener = onRefreshListener;
}

/**
 * Set a text to represent when the list was last updated. 
 * @param lastUpdated Last updated at.
 */
public void setLastUpdated(CharSequence lastUpdated) {
    if (lastUpdated != null) {
        mRefreshViewLastUpdated.setVisibility(View.VISIBLE);
        mRefreshViewLastUpdated.setText(lastUpdated);
    } else {
        mRefreshViewLastUpdated.setVisibility(View.GONE);
    }
}

@Override
public boolean onTouchEvent(MotionEvent event) {
    final int y = (int) event.getY();
    mBounceHack = false;

    switch (event.getAction()) {
        case MotionEvent.ACTION_UP:
            if (!isVerticalScrollBarEnabled()) {
                setVerticalScrollBarEnabled(true);
            }
            if (getFirstVisiblePosition() == 0 && mRefreshState != REFRESHING) {
                if ((mRefreshView.getBottom() >= mRefreshViewHeight
                        || mRefreshView.getTop() >= 0)
                        && mRefreshState == RELEASE_TO_REFRESH) {
                    // Initiate the refresh
                    mRefreshState = REFRESHING;
                    prepareForRefresh();
                    onRefresh();
                } else if (mRefreshView.getBottom() < mRefreshViewHeight
                        || mRefreshView.getTop() <= 0) {
                    // Abort refresh and scroll down below the refresh view
                    resetHeader();
                    setSelection(1);
                }
            }
            break;
        case MotionEvent.ACTION_DOWN:
            mLastMotionY = y;
            break;
        case MotionEvent.ACTION_MOVE:
            applyHeaderPadding(event);
            break;
    }
    return super.onTouchEvent(event);
}

private void applyHeaderPadding(MotionEvent ev) {
    // getHistorySize has been available since API 1
    int pointerCount = ev.getHistorySize();

    for (int p = 0; p < pointerCount; p++) {
        if (mRefreshState == RELEASE_TO_REFRESH) {
            if (isVerticalFadingEdgeEnabled()) {
                setVerticalScrollBarEnabled(false);
            }

            int historicalY = (int) ev.getHistoricalY(p);

            // Calculate the padding to apply, we divide by 1.7 to
            // simulate a more resistant effect during pull.
            int topPadding = (int) (((historicalY - mLastMotionY)
                    - mRefreshViewHeight) / 1.7);

            mRefreshView.setPadding(
                    mRefreshView.getPaddingLeft(),
                    topPadding,
                    mRefreshView.getPaddingRight(),
                    mRefreshView.getPaddingBottom());
        }
    }
}

/**
 * Sets the header padding back to original size.
 */
private void resetHeaderPadding() {
    mRefreshView.setPadding(
            mRefreshView.getPaddingLeft(),
            mRefreshOriginalTopPadding,
            mRefreshView.getPaddingRight(),
            mRefreshView.getPaddingBottom());
}

/**
 * Resets the header to the original state.
 */
private void resetHeader() {
    if (mRefreshState != TAP_TO_REFRESH) {
        mRefreshState = TAP_TO_REFRESH;

        resetHeaderPadding();

        // Set refresh view text to the pull label
        mRefreshViewText.setText(R.string.pull_to_refresh_tap_label);
        // Replace refresh drawable with arrow drawable
        mRefreshViewImage.setImageResource(R.drawable.ic_pulltorefresh_arrow);
        // Clear the full rotation animation
        mRefreshViewImage.clearAnimation();
        // Hide progress bar and arrow.
        mRefreshViewImage.setVisibility(View.GONE);
        mRefreshViewProgress.setVisibility(View.GONE);
    }
}

private void measureView(View child) {
    ViewGroup.LayoutParams p = child.getLayoutParams();
    if (p == null) {
        p = new ViewGroup.LayoutParams(
                ViewGroup.LayoutParams.FILL_PARENT,
                ViewGroup.LayoutParams.WRAP_CONTENT);
    }

    int childWidthSpec = ViewGroup.getChildMeasureSpec(0,
            0 + 0, p.width);
    int lpHeight = p.height;
    int childHeightSpec;
    if (lpHeight > 0) {
        childHeightSpec = MeasureSpec.makeMeasureSpec(lpHeight, MeasureSpec.EXACTLY);
    } else {
        childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
    }
    child.measure(childWidthSpec, childHeightSpec);
}

@Override
public void onScroll(AbsListView view, int firstVisibleItem,
        int visibleItemCount, int totalItemCount) {
    // When the refresh view is completely visible, change the text to say
    // "Release to refresh..." and flip the arrow drawable.
    if (mCurrentScrollState == SCROLL_STATE_TOUCH_SCROLL
            && mRefreshState != REFRESHING) {
        if (firstVisibleItem == 0) {
            mRefreshViewImage.setVisibility(View.VISIBLE);
            if ((mRefreshView.getBottom() >= mRefreshViewHeight + 20
                    || mRefreshView.getTop() >= 0)
                    && mRefreshState != RELEASE_TO_REFRESH) {
                mRefreshViewText.setText(R.string.pull_to_refresh_release_label);
                mRefreshViewImage.clearAnimation();
                mRefreshViewImage.startAnimation(mFlipAnimation);
                mRefreshState = RELEASE_TO_REFRESH;
            } else if (mRefreshView.getBottom() < mRefreshViewHeight + 20
                    && mRefreshState != PULL_TO_REFRESH) {
                mRefreshViewText.setText(R.string.pull_to_refresh_pull_label);
                if (mRefreshState != TAP_TO_REFRESH) {
                    mRefreshViewImage.clearAnimation();
                    mRefreshViewImage.startAnimation(mReverseFlipAnimation);
                }
                mRefreshState = PULL_TO_REFRESH;
            }
        } else {
            mRefreshViewImage.setVisibility(View.GONE);
            resetHeader();
        }
    } else if (mCurrentScrollState == SCROLL_STATE_FLING
            && firstVisibleItem == 0
            && mRefreshState != REFRESHING) {
        setSelection(1);
        mBounceHack = true;
    } else if (mBounceHack && mCurrentScrollState == SCROLL_STATE_FLING) {
        setSelection(1);
    }

    if (mOnScrollListener != null) {
        mOnScrollListener.onScroll(view, firstVisibleItem,
                visibleItemCount, totalItemCount);
    }
}

@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
    mCurrentScrollState = scrollState;

    if (mCurrentScrollState == SCROLL_STATE_IDLE) {
        mBounceHack = false;
    }

    if (mOnScrollListener != null) {
        mOnScrollListener.onScrollStateChanged(view, scrollState);
    }
}

public void prepareForRefresh() {
    resetHeaderPadding();

    mRefreshViewImage.setVisibility(View.GONE);
    // We need this hack, otherwise it will keep the previous drawable.
    mRefreshViewImage.setImageDrawable(null);
    mRefreshViewProgress.setVisibility(View.VISIBLE);

    // Set refresh view text to the refreshing label
    mRefreshViewText.setText(R.string.pull_to_refresh_refreshing_label);

    mRefreshState = REFRESHING;
}

public void onRefresh() {
    Log.d(TAG, "onRefresh");

    if (mOnRefreshListener != null) {
        mOnRefreshListener.onRefresh();
    }
}

/**
 * Resets the list to a normal state after a refresh.
 * @param lastUpdated Last updated at.
 */
public void onRefreshComplete(CharSequence lastUpdated) {
    setLastUpdated(lastUpdated);
    onRefreshComplete();
}

/**
 * Resets the list to a normal state after a refresh.
 */
public void onRefreshComplete() {        
    Log.d(TAG, "onRefreshComplete");

    resetHeader();

    // If refresh view is visible when loading completes, scroll down to
    // the next item.
    if (getFirstVisiblePosition() == 0) {
        invalidateViews();
        setSelection(1);
    }
}

/**
 * Invoked when the refresh view is clicked on. This is mainly used when
 * there's only a few items in the list and it's not possible to drag the
 * list.
 */
private class OnClickRefreshListener implements OnClickListener {

    @Override
    public void onClick(View v) {
        if (mRefreshState != REFRESHING) {
            prepareForRefresh();
            onRefresh();
        }
    }

}

/**
 * Interface definition for a callback to be invoked when list should be
 * refreshed.
 */
public interface OnRefreshListener {
    /**
     * Called when the list should be refreshed.
     * <p>
     * A call to {@link PullToRefreshListView #onRefreshComplete()} is
     * expected to indicate that the refresh has completed.
     */
    public void onRefresh();
}
}

这是我运行应用程序时的logcat错误:

 10-20 05:26:12.867: E/AndroidRuntime(2633): FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.zanqi.testtest/com.zanqi.testtest.MainActivity}: java.lang.NullPointerException
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2211)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261)
    at android.app.ActivityThread.access$600(ActivityThread.java:141)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:137)
    at android.app.ActivityThread.main(ActivityThread.java:5103)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:525)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
    at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
    at com.zanqi.testtest.MainActivity.onCreate(MainActivity.java:67)
    at android.app.Activity.performCreate(Activity.java:5133)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2175)
    ... 11 more

1 个答案:

答案 0 :(得分:0)

您没有初始化列表(PullToRefreshListView的实例)请在您的oncreate方法中添加以下行

list = (PullToRefreshListView) findViewById(R.id.yourlistviewid);

然后调用setOnRefreshListener。还要初始化您要使用的其他变量。