要实现多页滑动效果,主要是需要处理onTouchEvent和onInterceptTouchEvent,要处理好touch事件的子控件和父控件的传递问题。

滚动控制可以利用android的Scroller来实现。

这里提供两种做法:

1、自定义MFlipper控件,从ViewGroup继承,利用Scroller实现滚动,重点是onTouchEvent和onInterceptTouchEvent的重写,

要注意什么时候该返回true,什么时候false。否则会导致界面滑动和界面内按钮点击事件相冲突。

由于采用了ViewGroup来管理子view,只适合于页面数较少而且较固定的情况,因为viewgroup需要一开始就调用addView,把所有view都加进去并layout,

太多页面会有内存问题。如果是页面很多,而且随时动态增长的话,就需要考虑对view做cache和动态创建,动态layout,具体做法参考下面的方法二;

2、从AdapterView继承,参考Android自带ListView的实现,实现子view动态创建和cache,滑动效果等。

源码如下:

    1. import android.content.Context;
    2. import android.util.AttributeSet;
    3. import android.util.Log;
    4. import android.util.SparseArray;
    5. import android.view.MotionEvent;
    6. import android.view.VelocityTracker;
    7. import android.view.View;
    8. import android.view.ViewConfiguration;
    9. import android.view.ViewGroup;
    10. import android.widget.AdapterView;
    11. import android.widget.BaseAdapter;
    12. import android.widget.Gallery;
    13. import android.widget.Scroller;
    14. /**
    15. * 自定义一个横向滚动的AdapterView,类似与全屏的Gallery,但是一次只滚动一屏,而且每一屏支持子view的点击处理
    16. * @author weibinke
    17. *
    18. */
    19. public class MultiPageSwitcher extends AdapterView<BaseAdapter> {
    20. private BaseAdapter mAdapter = null;
    21. private Scroller mScroller;
    22. private int mTouchSlop;
    23. private float mTouchStartX;
    24. private float mLastMotionX;
    25. private final static String TAG = "MultiPageSwitcher";
    26. private int mLastScrolledOffset = 0;
    27. /** User is not touching the list */
    28. private static final int TOUCH_STATE_RESTING = 0;
    29. /** User is scrolling the list */
    30. private static final int TOUCH_STATE_SCROLL = 2;
    31. private int mTouchState = TOUCH_STATE_RESTING;
    32. private int mHeightMeasureSpec;
    33. private int mWidthMeasureSpec;
    34. private int mSelectedPosition;
    35. private int mFirstPosition;                                //第一个可见view的position
    36. private int mCurrentSelectedPosition;
    37. private VelocityTracker mVelocityTracker;
    38. private static final int SNAP_VELOCITY = 600;
    39. protected RecycleBin mRecycler = new RecycleBin();
    40. private OnPostionChangeListener mOnPostionChangeListener = null;
    41. public MultiPageSwitcher(Context context, AttributeSet attrs) {
    42. super(context, attrs);
    43. mScroller = new Scroller(context);
    44. mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
    45. }
    46. @Override
    47. protected void onLayout(boolean changed, int left, int top, int right,
    48. int bottom) {
    49. // TODO Auto-generated method stub
    50. MLog.d("MultiPageSwitcher.onlayout start");
    51. super.onLayout(changed, left, top, right, bottom);
    52. if (mAdapter == null) {
    53. return ;
    54. }
    55. recycleAllViews();
    56. detachAllViewsFromParent();
    57. mRecycler.clear();
    58. fillAllViews();
    59. MLog.d("MultiPageSwitcher.onlayout end");
    60. }
    61. /**
    62. * 从当前可见的view向左边填充
    63. */
    64. private void fillToGalleryLeft() {
    65. int itemSpacing = 0;
    66. int galleryLeft = 0;
    67. // Set state for initial iteration
    68. View prevIterationView = getChildAt(0);
    69. int curPosition;
    70. int curRightEdge;
    71. if (prevIterationView != null) {
    72. curPosition = mFirstPosition - 1;
    73. curRightEdge = prevIterationView.getLeft() - itemSpacing;
    74. } else {
    75. // No children available!
    76. curPosition = 0;
    77. curRightEdge = getRight() - getLeft();
    78. }
    79. while (curRightEdge > galleryLeft && curPosition >= 0) {
    80. prevIterationView = makeAndAddView(curPosition, curPosition - mSelectedPosition,
    81. curRightEdge, false);
    82. // Remember some state
    83. mFirstPosition = curPosition;
    84. // Set state for next iteration
    85. curRightEdge = prevIterationView.getLeft() - itemSpacing;
    86. curPosition--;
    87. }
    88. }
    89. private void fillToGalleryRight() {
    90. int itemSpacing = 0;
    91. int galleryRight = getRight() - getLeft();
    92. int numChildren = getChildCount();
    93. int numItems = mAdapter.getCount();
    94. // Set state for initial iteration
    95. View prevIterationView = getChildAt(numChildren - 1);
    96. int curPosition;
    97. int curLeftEdge;
    98. if (prevIterationView != null) {
    99. curPosition = mFirstPosition + numChildren;
    100. curLeftEdge = prevIterationView.getRight() + itemSpacing;
    101. } else {
    102. mFirstPosition = curPosition = numItems - 1;
    103. curLeftEdge = 0;
    104. }
    105. while (curLeftEdge < galleryRight && curPosition < numItems) {
    106. prevIterationView = makeAndAddView(curPosition, curPosition - mSelectedPosition,
    107. curLeftEdge, true);
    108. // Set state for next iteration
    109. curLeftEdge = prevIterationView.getRight() + itemSpacing;
    110. curPosition++;
    111. }
    112. }
    113. /**
    114. *填充view
    115. */
    116. private void fillAllViews(){
    117. //先创建第一个view,使其居中显示
    118. if (mSelectedPosition >= mAdapter.getCount()&& mSelectedPosition > 0) {
    119. //处理被记录被删除导致当前选中位置超出记录数的情况
    120. mSelectedPosition = mAdapter.getCount() - 1;
    121. if(mOnPostionChangeListener != null){
    122. mCurrentSelectedPosition = mSelectedPosition;
    123. mOnPostionChangeListener.onPostionChange(this, mCurrentSelectedPosition);
    124. }
    125. }
    126. mFirstPosition = mSelectedPosition;
    127. mCurrentSelectedPosition = mSelectedPosition;
    128. View child = makeAndAddView(mSelectedPosition, 0, 0, true);
    129. int offset = getWidth() / 2 - (child.getLeft() + child.getWidth() / 2);
    130. child.offsetLeftAndRight(offset);
    131. fillToGalleryLeft();
    132. fillToGalleryRight();
    133. }
    134. /**
    135. * Obtain a view, either by pulling an existing view from the recycler or by
    136. * getting a new one from the adapter. If we are animating, make sure there
    137. * is enough information in the view's layout parameters to animate from the
    138. * old to new positions.
    139. *
    140. * @param position Position in the gallery for the view to obtain
    141. * @param offset Offset from the selected position
    142. * @param x X-coordintate indicating where this view should be placed. This
    143. *        will either be the left or right edge of the view, depending on
    144. *        the fromLeft paramter
    145. * @param fromLeft Are we posiitoning views based on the left edge? (i.e.,
    146. *        building from left to right)?
    147. * @return A view that has been added to the gallery
    148. */
    149. private View makeAndAddView(int position, int offset, int x,
    150. boolean fromLeft) {
    151. View child;
    152. //ask the adapter for a view
    153. child = mAdapter.getView(position, null, this);
    154. // Position the view
    155. setUpChild(child, offset, x, fromLeft);
    156. return child;
    157. }
    158. @Override
    159. protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
    160. /*
    161. * Gallery expects Gallery.LayoutParams.
    162. */
    163. return new Gallery.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
    164. ViewGroup.LayoutParams.WRAP_CONTENT);
    165. }
    166. /**
    167. * Helper for makeAndAddView to set the position of a view and fill out its
    168. * layout paramters.
    169. *
    170. * @param child The view to position
    171. * @param offset Offset from the selected position
    172. * @param x X-coordintate indicating where this view should be placed. This
    173. *        will either be the left or right edge of the view, depending on
    174. *        the fromLeft paramter
    175. * @param fromLeft Are we posiitoning views based on the left edge? (i.e.,
    176. *        building from left to right)?
    177. */
    178. private void setUpChild(View child, int offset, int x, boolean fromLeft) {
    179. // Respect layout params that are already in the view. Otherwise
    180. // make some up...
    181. Gallery.LayoutParams lp = (Gallery.LayoutParams)
    182. child.getLayoutParams();
    183. if (lp == null) {
    184. lp = (Gallery.LayoutParams) generateDefaultLayoutParams();
    185. }
    186. addViewInLayout(child, fromLeft ? -1 : 0, lp);
    187. child.setSelected(offset == 0);
    188. // Get measure specs
    189. int childHeightSpec = ViewGroup.getChildMeasureSpec(mHeightMeasureSpec,
    190. 0, lp.height);
    191. int childWidthSpec = ViewGroup.getChildMeasureSpec(mWidthMeasureSpec,
    192. 0, lp.width);
    193. // Measure child
    194. child.measure(childWidthSpec, childHeightSpec);
    195. int childLeft;
    196. int childRight;
    197. // Position vertically based on gravity setting
    198. int childTop = 0;
    199. int childBottom = childTop + child.getMeasuredHeight();
    200. int width = child.getMeasuredWidth();
    201. if (fromLeft) {
    202. childLeft = x;
    203. childRight = childLeft + width;
    204. } else {
    205. childLeft = x - width;
    206. childRight = x;
    207. }
    208. child.layout(childLeft, childTop, childRight, childBottom);
    209. }
    210. @Override
    211. protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    212. // TODO Auto-generated method stub
    213. super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    214. mWidthMeasureSpec = widthMeasureSpec;
    215. mHeightMeasureSpec = heightMeasureSpec;
    216. }
    217. @Override
    218. public int getCount() {
    219. // TODO Auto-generated method stub
    220. return mAdapter.getCount();
    221. }
    222. @Override
    223. public BaseAdapter getAdapter() {
    224. // TODO Auto-generated method stub
    225. return mAdapter;
    226. }
    227. @Override
    228. public void setAdapter(BaseAdapter adapter) {
    229. // TODO Auto-generated method stub
    230. mAdapter = adapter;
    231. removeAllViewsInLayout();
    232. requestLayout();
    233. }
    234. @Override
    235. public View getSelectedView() {
    236. // TODO Auto-generated method stub
    237. return null;
    238. }
    239. @Override
    240. public void setSelection(int position) {
    241. // TODO Auto-generated method stub
    242. }
    243. @Override
    244. public boolean onInterceptTouchEvent(MotionEvent event) {
    245. if (!mScroller.isFinished()) {
    246. return true;
    247. }
    248. final int action = event.getAction();
    249. MLog.d("onInterceptTouchEvent action = "+event.getAction());
    250. if (MotionEvent.ACTION_DOWN == action) {
    251. startTouch(event);
    252. return false;
    253. }else if (MotionEvent.ACTION_MOVE == action) {
    254. return startScrollIfNeeded(event);
    255. }else if (MotionEvent.ACTION_UP == action || MotionEvent.ACTION_CANCEL == action) {
    256. mTouchState = TOUCH_STATE_RESTING;
    257. return false;
    258. }
    259. return false;
    260. }
    261. @Override
    262. public boolean onTouchEvent(MotionEvent event) {
    263. if (!mScroller.isFinished()) {
    264. return true;
    265. }
    266. if (mVelocityTracker == null) {
    267. mVelocityTracker = VelocityTracker.obtain();
    268. }
    269. mVelocityTracker.addMovement(event);
    270. MLog.d("onTouchEvent action = "+event.getAction());
    271. final int action = event.getAction();
    272. final float x = event.getX();
    273. if (MotionEvent.ACTION_DOWN == action) {
    274. startTouch(event);
    275. }else if (MotionEvent.ACTION_MOVE == action) {
    276. if (mTouchState == TOUCH_STATE_RESTING) {
    277. startScrollIfNeeded(event);
    278. }else if (mTouchState == TOUCH_STATE_SCROLL) {
    279. int deltaX = (int)(x - mLastMotionX);
    280. mLastMotionX = x;
    281. scrollDeltaX(deltaX);
    282. }
    283. }else if (MotionEvent.ACTION_UP == action || MotionEvent.ACTION_CANCEL == action) {
    284. if (mTouchState == TOUCH_STATE_SCROLL) {
    285. onUp(event);
    286. }
    287. }
    288. return true;
    289. }
    290. private void scrollDeltaX(int deltaX){
    291. //先把现有的view坐标移动
    292. for (int i = 0; i < getChildCount(); i++) {
    293. getChildAt(i).offsetLeftAndRight(deltaX);
    294. }
    295. boolean toLeft = (deltaX < 0);
    296. detachOffScreenChildren(toLeft);
    297. if (deltaX < 0) {
    298. //sroll to right
    299. fillToGalleryRight();
    300. }else {
    301. fillToGalleryLeft();
    302. }
    303. invalidate();
    304. int position = calculteCenterItem() + mFirstPosition;
    305. if (mCurrentSelectedPosition != position) {
    306. mCurrentSelectedPosition = position;
    307. if (mOnPostionChangeListener != null) {
    308. mOnPostionChangeListener.onPostionChange(this, mCurrentSelectedPosition);
    309. }
    310. }
    311. }
    312. private void onUp(MotionEvent event){
    313. final VelocityTracker velocityTracker = mVelocityTracker;
    314. velocityTracker.computeCurrentVelocity(1000);
    315. int velocityX = (int) velocityTracker.getXVelocity();
    316. MLog.d( "onUp velocityX:"+velocityX);
    317. if (velocityX < -SNAP_VELOCITY && mSelectedPosition < mAdapter.getCount() - 1) {
    318. if (scrollToChild(mSelectedPosition + 1)) {
    319. mSelectedPosition ++;
    320. }
    321. }else if (velocityX > SNAP_VELOCITY && mSelectedPosition > 0) {
    322. if (scrollToChild(mSelectedPosition - 1)) {
    323. mSelectedPosition --;
    324. }
    325. }else{
    326. int position = calculteCenterItem();
    327. int newpostion = mFirstPosition + position;
    328. if (scrollToChild(newpostion)) {
    329. mSelectedPosition = newpostion;
    330. }
    331. }
    332. if (mVelocityTracker != null) {
    333. mVelocityTracker.recycle();
    334. mVelocityTracker = null;
    335. }
    336. mTouchState = TOUCH_STATE_RESTING;
    337. }
    338. /**
    339. * 计算最接近中心点的view
    340. * @return
    341. */
    342. private int calculteCenterItem(){
    343. View child = null;
    344. int lastpostion = 0;
    345. int lastclosestDistance = 0;
    346. int viewCenter = getLeft() + getWidth() / 2;
    347. for (int i = 0; i < getChildCount(); i++) {
    348. child = getChildAt(i);
    349. if (child.getLeft() < viewCenter && child.getRight() > viewCenter ) {
    350. lastpostion = i;
    351. break;
    352. }else {
    353. int childClosestDistance = Math.min(Math.abs(child.getLeft() - viewCenter), Math.abs(child.getRight() - viewCenter));
    354. if (childClosestDistance < lastclosestDistance) {
    355. lastclosestDistance = childClosestDistance;
    356. lastpostion = i;
    357. }
    358. }
    359. }
    360. return lastpostion;
    361. }
    362. public void moveNext(){
    363. if (!mScroller.isFinished()) {
    364. return;
    365. }
    366. if (0 <= mSelectedPosition && mSelectedPosition < mAdapter.getCount() - 1) {
    367. if (scrollToChild(mSelectedPosition + 1)) {
    368. mSelectedPosition ++;
    369. }else {
    370. makeAndAddView(mSelectedPosition + 1, 1, getWidth(), true);
    371. if (scrollToChild(mSelectedPosition + 1)) {
    372. mSelectedPosition ++;
    373. }
    374. }
    375. }
    376. }
    377. public void movePrevious(){
    378. if (!mScroller.isFinished()) {
    379. return;
    380. }
    381. if (0 < mSelectedPosition && mSelectedPosition < mAdapter.getCount()) {
    382. if (scrollToChild(mSelectedPosition -1)) {
    383. mSelectedPosition --;
    384. }else {
    385. makeAndAddView(mSelectedPosition - 1, -1, 0, false);
    386. mFirstPosition = mSelectedPosition - 1;
    387. if (scrollToChild(mSelectedPosition - 1)) {
    388. mSelectedPosition --;
    389. }
    390. }
    391. }
    392. }
    393. private boolean scrollToChild(int position){
    394. MLog.d( "scrollToChild positionm,FirstPosition,childcount:"+position + "," + mFirstPosition+ "," + getChildCount());
    395. View child = getChildAt(position - mFirstPosition );
    396. if (child != null) {
    397. int distance = getWidth() / 2 - (child.getLeft() + child.getWidth() / 2);
    398. mLastScrolledOffset = 0;
    399. mScroller.startScroll(0, 0, distance, 0,200);
    400. invalidate();
    401. return true;
    402. }
    403. MLog.d( "scrollToChild some error happened");
    404. return false;
    405. }
    406. @Override
    407. public void computeScroll() {
    408. if (mScroller.computeScrollOffset()) {
    409. int scrollX = mScroller.getCurrX();
    410. scrollDeltaX(scrollX - mLastScrolledOffset);
    411. mLastScrolledOffset = scrollX;
    412. postInvalidate();
    413. }
    414. }
    415. private void startTouch(MotionEvent event){
    416. mTouchStartX = event.getX();
    417. mTouchState = mScroller.isFinished()? TOUCH_STATE_RESTING : TOUCH_STATE_SCROLL;
    418. mLastMotionX = mTouchStartX;
    419. }
    420. private boolean startScrollIfNeeded(MotionEvent event){
    421. final int xPos = (int)event.getX();
    422. mLastMotionX = event.getX();
    423. if (xPos < mTouchStartX - mTouchSlop
    424. || xPos > mTouchStartX + mTouchSlop
    425. ) {
    426. // we've moved far enough for this to be a scroll
    427. mTouchState = TOUCH_STATE_SCROLL;
    428. return true;
    429. }
    430. return false;
    431. }
    432. /**
    433. * Detaches children that are off the screen (i.e.: Gallery bounds).
    434. *
    435. * @param toLeft Whether to detach children to the left of the Gallery, or
    436. *            to the right.
    437. */
    438. private void detachOffScreenChildren(boolean toLeft) {
    439. int numChildren = getChildCount();
    440. int start = 0;
    441. int count = 0;
    442. int firstPosition = mFirstPosition;
    443. if (toLeft) {
    444. final int galleryLeft = 0;
    445. for (int i = 0; i < numChildren; i++) {
    446. final View child = getChildAt(i);
    447. if (child.getRight() >= galleryLeft) {
    448. break;
    449. } else {
    450. count++;
    451. mRecycler.put(firstPosition + i, child);
    452. }
    453. }
    454. } else {
    455. final int galleryRight = getWidth();
    456. for (int i = numChildren - 1; i >= 0; i--) {
    457. final View child = getChildAt(i);
    458. if (child.getLeft() <= galleryRight) {
    459. break;
    460. } else {
    461. start = i;
    462. count++;
    463. mRecycler.put(firstPosition + i, child);
    464. }
    465. }
    466. }
    467. detachViewsFromParent(start, count);
    468. if (toLeft) {
    469. mFirstPosition += count;
    470. }
    471. mRecycler.clear();
    472. }
    473. public void setOnPositionChangeListen(OnPostionChangeListener onPostionChangeListener){
    474. mOnPostionChangeListener = onPostionChangeListener;
    475. }
    476. public int getCurrentSelectedPosition(){
    477. return mCurrentSelectedPosition;
    478. }
    479. /**
    480. * 刷新数据,本来想用AdapterView.AdapterDataSetObserver机制来实现的,但是整个逻辑移植比较麻烦,就暂时用这个替代了
    481. */
    482. public void updateData(){
    483. requestLayout();
    484. }
    485. private void recycleAllViews() {
    486. int childCount = getChildCount();
    487. final RecycleBin recycleBin = mRecycler;
    488. // All views go in recycler
    489. for (int i=0; i<childCount; i++) {
    490. View v = getChildAt(i);
    491. int index = mFirstPosition + i;
    492. recycleBin.put(index, v);
    493. }
    494. }
    495. class RecycleBin {
    496. private SparseArray<View> mScrapHeap = new SparseArray<View>();
    497. public void put(int position, View v) {
    498. if (mScrapHeap.get(position) != null) {
    499. Log.e(TAG,"RecycleBin put error.");
    500. }
    501. mScrapHeap.put(position, v);
    502. }
    503. View get(int position) {
    504. // System.out.print("Looking for " + position);
    505. View result = mScrapHeap.get(position);
    506. if (result != null) {
    507. MLog.d("RecycleBin get hit.");
    508. mScrapHeap.delete(position);
    509. } else {
    510. MLog.d("RecycleBin get Miss.");
    511. }
    512. return result;
    513. }
    514. View peek(int position) {
    515. // System.out.print("Looking for " + position);
    516. return mScrapHeap.get(position);
    517. }
    518. void clear() {
    519. final SparseArray<View> scrapHeap = mScrapHeap;
    520. final int count = scrapHeap.size();
    521. for (int i = 0; i < count; i++) {
    522. final View view = scrapHeap.valueAt(i);
    523. if (view != null) {
    524. removeDetachedView(view, true);
    525. }
    526. }
    527. scrapHeap.clear();
    528. }
    529. }
    530. public interface OnPostionChangeListener{
    531. abstract public void onPostionChange(View v,int position);
    532. }
    533. }

Android实现多页左右滑动效果,支持子view动态创建和cache的更多相关文章

  1. Android实现浮层的上下滑动(支持内部加入View)

    前言 我K.今天竟然是情人节.对于资深的单身狗来说,简直是个噩耗,今天注定是各种秀恩爱.心塞中.. .. 话题到此结束,管他什么情人节,今天给大家带来的是一个浮层的上下滑动,浮层滑动时分三种状态:所有 ...

  2. 011 Android TabLayout+ViewPager实现顶部滑动效果(多个页面)

    1.TabLayout介绍 TabLayout提供了一个水平的布局用来展示Tabs,很多应用都有这样的设计,典型的有网易新闻,简书,知乎等.TabLayout就可以很好的完成这一职责,首先TabLay ...

  3. android SlidingTabLayout实现ViewPager页卡滑动效果

    先来张效果图(能够滑动切换页卡) watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvcGVuZ2t2/font/5a6L5L2T/fontsize/400/fi ...

  4. Android使用GestureDetector实现手势滑动效果

    直接看实例: package com.example.gesturedetector; import android.os.Bundle; import android.app.Activity; i ...

  5. Android学习之-TextView的滑动效果

    textView中如何设置滚动条 在xml中定义: <TextView            android:layout_width="wrap_content"      ...

  6. Android实现左右滑动效果

    本示例演示在Android中实现图片左右滑动效果.   关于滑动效果,在Android中用得比较多,本示例实现的滑动效果是使用ViewFlipper来实现的,当然也可以使用其它的View来实现.接下来 ...

  7. Android 实现左右滑动效果ViewFlipper终结【转】

    本示例演示在Android中实现图片左右滑动效果.   关于滑动效果,在Android中用得比较多,本示例实现的滑动效果是使用ViewFlipper来实现的,当然也可以使用其它的View来实现.接下来 ...

  8. Android -- 常见控件的小效果

    1,EditText控件 ① 修改光标颜色 自定义drawable 创建cursor.xml文件 <?xml version="1.0" encoding="utf ...

  9. Android使用ViewFlipper实现左右滑动效果面

    在我的博客中,上次是使用ViewPager实现左右滑动的效果的,请看文章:Android使用ViewPager实现左右滑动效果. 这次我来使用ViewFlipper实现这种效果,好了,先看看效果吧: ...

随机推荐

  1. phpcms的增删改查操作整理

    一.查 ①select($where = '', $data = '*', $limit = '', $order = '', $group = '', $key='') /** * 执行sql查询 ...

  2. 50+ 响应式的Prestashop电商主题

    PrestaShop是一款针对web2.0设计的全功能.跨平台的免费开源电子商务解决方案,自08年1.0版本发布,短短两年时间,发展迅速,全球已超过四万家网店采用Prestashop进行部署.Pres ...

  3. 14个超赞的响应式HTML5模板免费下载

    现在HTML5已经势不可挡.很多朋友开始学习HTML5,当你已经学习过一些HTML5的教程之后,是不是想立即开始实战了呢?对,现在就开始吧,不过 找一些优秀的HTML5模板案例练习是相当不错的注意.当 ...

  4. navicat 或者workbench 无法连接127.0.0.1(61)的解决方法

    1.输入mysql -uroot 进入命令行模式, 2.输入"show variables like '%sock%';"查看sock文件所在位置 如: 3.配置客户端(以navi ...

  5. 未能加载文件或程序集“Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed”或它的某一个依赖项。找到的程序集清单定义与程序集引用不匹配。

    未能加载文件或程序集“Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed”或它的某一个 ...

  6. 转】Maven学习总结(九)——使用Nexus搭建Maven私服

    原博文出自于:http://www.cnblogs.com/xdp-gacl/p/4068967.html 感谢! 一.搭建nexus私服的目的 为什么要搭建nexus私服,原因很简单,有些公司都不提 ...

  7. How Tomcat Works(十四)

    我们已经知道,在tomcat中有四种类型的servlet容器,分别为Engine.Host.Context 和Wrapper,本文接下来对tomcat中Wrapper接口的标准实现进行说明. 对于每个 ...

  8. 使用struts2实现文件上传

    action中 private File file;//文件 private String fileFileName;//文件名字 固定格式name+FileName private String f ...

  9. Eclipse 和 NetBeans 快捷键即其他常用功能比较

    按: 自己用 Eclipse, 常用的也就这些功能, 在用 NetBeans 时, 有些不顺手, 因此列表如下. Eclipse和NetBeans常用快捷键对比:  功能  Eclipse     N ...

  10. Mac生存手册

    最近刚从Linux转到了Mac系统上,感觉好的地方是再也不折腾了,什么GNOME, KDE, XFCE,各种发行版本都远离我而去了.当然Mac下很多好软件都是要付费的,我只能绕着走了: 1. 命令行, ...