CycleScrollView.java

package com.example.test;

import android.content.Context;
import android.graphics.Rect;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Scroller; @SuppressWarnings("deprecation")
public class CycleScrollView<T> extends ViewGroup implements OnGestureListener { static final String TAG = "CycleScrollView";
Context mContext; /**
* Scroll velocity.
*/
public static final long SCROLL_VELOCITY = 50; /**
* Scroll offset.
*/
public static final int SCROLL_OFFSET = -1; /**
* Touch delay.
*/
public static final long TOUCH_DELAYMILLIS = 2000; /**
* Fling duration.
*/
public static final int FLING_DURATION = 2000; /**
* Filing max velocity x.
*/
public static final int MAX_VELOCITY_X = 1000; private GestureDetector detector;
private Handler mHandler;
private Scroller mScroller; /**
* Callback interface adapter and OnItemClick.
*/
private CycleScrollAdapter<T> mAdapter;
private OnItemClickListener mOnItemClickListener; /**
* Scroll index
*/
private int mPreIndex;
private int mCurrentIndex;
private int mNextIndex;
private View mCurrentView;
private View mPreView;
private View mNextView; private float mLastMotionX; // The reLayout is false can not invoke onLayout.
private boolean reLayout = false; // If the item count more than screen that can scroll.
private boolean canScroll = false; // A flag for switch current view.
private boolean mCurrentViewAtLeft = true; // Fling distance.
private int mFlingX = 0; private boolean isMoveAction = false; private int defaultItemY = 10; private int maxItemCount = 7; private int initItemX = 20; /**
* The screen width.
*/
private int screenWidth; /**
* Item view height.
*/
private int itemHeight; /**
* Item view width.
*/
private int itemWidth; /**
* Item view layout x.
*/
private int itemX = getInitItemX(); /**
* Item view layout y.
*/
private int itemY = defaultItemY; // Auto scroll view task.
private final Runnable mScrollTask = new Runnable() { @Override
public void run() {
if (canScroll) {
scrollView(SCROLL_OFFSET);
mHandler.postDelayed(this, SCROLL_VELOCITY);// Loop self.
}
}
}; public CycleScrollView(Context context) {
super(context);
onCreate(context);
} public CycleScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
onCreate(context);
} public CycleScrollView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
onCreate(context);
} private void onCreate(Context context) {
mContext = context;
detector = new GestureDetector(this);
mHandler = new Handler();
mScroller = new Scroller(context);
} /**
* Create scroll index.
*/
public void createIndex() {
if (canScroll) {
mPreIndex = maxItemCount - 1;
mCurrentIndex = 0;
mNextIndex = 1;
mPreView = getChildAt(mPreIndex);
mCurrentView = getChildAt(mCurrentIndex);
mNextView = getChildAt(mNextIndex);
}
} /**
* Set item click callback.
*
* @param onItemClickListener
* The callback
*/
public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
mOnItemClickListener = onItemClickListener;
} /**
* Set itemAdapter for addItem and bindItem.
*
* @param itemAdapter
*/
public void setAdapter(CycleScrollAdapter<T> adapter) {
mAdapter = adapter;
} /**
* Start auto scroll.
*/
public void startScroll() {
if (canScroll) {
mHandler.post(mScrollTask);
}
} /**
* Stop auto scroll and filing scroll task.
*/
public void stopScroll() {
mHandler.removeCallbacks(mScrollTask);
} /**
* Delay start auto scroll task.
*/
public void delayStartScroll() {
if (canScroll) {
mHandler.postDelayed(mScrollTask, TOUCH_DELAYMILLIS);
}
} @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int count = this.getChildCount();
for (int i = 0; i < count; i++) {
View child = this.getChildAt(i);
child.measure(widthMeasureSpec, heightMeasureSpec);
}
} @Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
/**
* On layout set the child view layout by x y width and height.
*/
if (reLayout) {// Run one times.
for (int i = 0; i < getChildCount(); i++) {
View child = this.getChildAt(i);
child.setVisibility(View.VISIBLE);
child.layout(itemX, getItemY(), itemX + getItemWidth(),
getItemY() + getItemHeight());
itemX += getItemMargin();
}
reLayout = !reLayout;
}
} /**
* When fling view run the fling task scroll view.
*/
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) { if (e1 == null || e2 == null) {
return false;
} // When deltaX and velocityX not good return false.
if (Math.abs(velocityX) < MAX_VELOCITY_X) {
return false;
} // Get the delta x.
float deltaX = (e1.getX() - e2.getX()); /**
* If can fling stop other scroll task at first , delay the task after
* fling.
*/
mHandler.removeCallbacks(mScrollTask);
if (canScroll) {
mHandler.postDelayed(mScrollTask, TOUCH_DELAYMILLIS
+ FLING_DURATION - 1000);
} /**
* The flingX is fling distance.
*/
mFlingX = (int) deltaX; // Start scroll with fling x.
mScroller.startScroll(0, 0, mFlingX, 0, FLING_DURATION);
return false;
} @Override
public void computeScroll() {
if (canScroll && mScroller.computeScrollOffset()) {
/**
* The Scroller.getCurrX() approach mFlingX , the deltaX more and
* more small.
*/
int deltaX = mFlingX - mScroller.getCurrX();
scrollView(-deltaX / 10);
postInvalidate();
}
} /**
* When touch event is move scroll child view.
*/
@Override
public boolean onTouchEvent(MotionEvent ev) { // Get event x,y at parent view.
final float x = ev.getX(); /**
* Get event x,y at screen.
*/
final int rawX = (int) ev.getRawX();
final int rawY = (int) ev.getRawY(); switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
// Reset isMoveAction.
isMoveAction = false;
// Get motionX.
mLastMotionX = x;
break;
case MotionEvent.ACTION_MOVE:
// When action move set isMoveAction true.
isMoveAction = true;
// Only support one pointer.
if (ev.getPointerCount() == 1) {
// Compute delta X.
int deltaX = 0;
deltaX = (int) (x - mLastMotionX);
mLastMotionX = x;
// When canScroll is true, scrollView width deltaX.
if (canScroll) {
scrollView(deltaX);
}
}
break;
case MotionEvent.ACTION_UP:
/**
* If not move find click item and invoke click event.
*/
if (!isMoveAction) {
View view = getClickItem(rawX, rawY);
if (view != null) {
mOnItemClickListener.onItemClick(Integer.valueOf(view
.getTag().toString()));
}
}
break;
}
return this.detector.onTouchEvent(ev);
} /**
* Get click item view by rawX and rawY.
* @param rawX the x at screen.
* @param rawY the y at screen.
* @return the click item view.
*/
private View getClickItem(final int rawX, final int rawY) {
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
// Get item view rect.
Rect rect = new Rect();
child.getGlobalVisibleRect(rect);
// If click point on the item view, invoke the click event.
if (rect.contains(rawX, rawY)) {
return child;
}
}
return null;
} /**
* Scroll view by delta x.
*
* @param deltaX
* The scroll distance.
*/
private void scrollView(int deltaX) {
// Move child view by deltaX.
moveChildView(deltaX);
// After move change index.
if (deltaX < 0) {// move left
// If current at right switch current view to left.
switchCurrentViewToLeft();
// change previous current next index.
moveToNext();
} else {// move right
// If current at left switch current view to right.
switchCurrentViewToRight();
// change previous current next index.
moveToPre();
}
invalidate();
} /**
* Move view by delta x.
*
* @param deltaX
* The move distance.
*/
private void moveChildView(int deltaX) {
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
child.layout(child.getLeft() + deltaX, child.getTop(),
child.getRight() + deltaX, child.getBottom());
}
} /**
* Current event is move to left, if current view at right switch current
* view to left.
*/
private void switchCurrentViewToLeft() {
if (!mCurrentViewAtLeft) {
mPreIndex = mCurrentIndex;
mCurrentIndex = mNextIndex;
mNextIndex++;
if (mNextIndex > maxItemCount - 1) {
mNextIndex = 0;
}
mCurrentView = getChildAt(mCurrentIndex);
mPreView = getChildAt(mPreIndex);
mNextView = getChildAt(mNextIndex);
mCurrentViewAtLeft = !mCurrentViewAtLeft;
}
} /**
* Current event is move to right, if current view at left switch current
* view to right.
*/
private void switchCurrentViewToRight() {
if (mCurrentViewAtLeft) {
mNextIndex = mCurrentIndex;
mCurrentIndex = mPreIndex;
mPreIndex--;
if (mPreIndex < 0) {
mPreIndex = maxItemCount - 1;
}
mCurrentView = getChildAt(mCurrentIndex);
mPreView = getChildAt(mPreIndex);
mNextView = getChildAt(mNextIndex);
mCurrentViewAtLeft = !mCurrentViewAtLeft;
}
} /**
* Current event is move to left,if current view move out of screen move the
* current view to right and reBind the item change index.
*/
private void moveToNext() {
if (mCurrentView.getRight() < 0) {
mCurrentView.layout(mPreView.getLeft() + getItemMargin(),
getItemY(), mPreView.getLeft() + getItemMargin()
+ getItemWidth(), getItemY() + getItemHeight()); if (mCurrentView.getTag() != null) {
int listIndex = (Integer) mCurrentView.getTag();
int index = (listIndex + maxItemCount) % mAdapter.getCount();
mAdapter.bindView(mCurrentView, mAdapter.get(index));
mCurrentView.setTag(index);
} mPreIndex = mCurrentIndex;
mCurrentIndex = mNextIndex;
mNextIndex++;
if (mNextIndex > maxItemCount - 1) {
mNextIndex = 0;
}
mCurrentView = getChildAt(mCurrentIndex);
mPreView = getChildAt(mPreIndex);
mNextView = getChildAt(mNextIndex);
moveToNext();
}
} /**
* Current event is move to right,if current view move out of screen move
* the current view to left and reBind the item change index.
*/
private void moveToPre() {
if (mCurrentView.getLeft() > getScreenWidth()) {
mCurrentView.layout(mNextView.getLeft() - getItemMargin(),
getItemY(), mNextView.getLeft() - getItemMargin()
+ getItemWidth(), getItemY() + getItemHeight()); if (mCurrentView.getTag() != null) {
int listIndex = (Integer) mCurrentView.getTag();
int index = (listIndex - maxItemCount + mAdapter.getCount())
% mAdapter.getCount();
mAdapter.bindView(mCurrentView, mAdapter.get(index));
mCurrentView.setTag(index);
} mNextIndex = mCurrentIndex;
mCurrentIndex = mPreIndex;
mPreIndex--;
if (mPreIndex < 0) {
mPreIndex = maxItemCount - 1;
}
mCurrentView = getChildAt(mCurrentIndex);
mPreView = getChildAt(mPreIndex);
mNextView = getChildAt(mNextIndex);
moveToPre();
}
} @Override
public boolean onDown(MotionEvent e) {
return true;
} @Override
public void onShowPress(MotionEvent e) {
} @Override
public boolean onSingleTapUp(MotionEvent e) {
return false;
} @Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
float distanceY) {
return false;
} @Override
public void onLongPress(MotionEvent e) {
} public int getMaxItemCount() {
return maxItemCount;
} public void setMaxItemCount(int maxItemCount) {
this.maxItemCount = maxItemCount;
} public void setReLayout(boolean reLayout) {
this.reLayout = reLayout;
} public void setCanScroll(boolean canScroll) {
this.canScroll = canScroll;
} public int getItemX() {
return itemX;
} public void setItemX(int itemX) {
this.itemX = itemX;
} public int getItemY() {
return itemY;
} public void setItemY(int itemY) {
this.itemY = itemY;
} public int getItemWidth() {
return itemWidth;
} public void setItemWidth(int itemWidth) {
this.itemWidth = itemWidth;
} public int getItemHeight() {
return itemHeight;
} public void setItemHeight(int itemHeight) {
this.itemHeight = itemHeight;
} public int getItemMargin() {
return (screenWidth - itemWidth * (maxItemCount - 1) - initItemX * 2)/(maxItemCount - 2) + itemWidth;
} public int getScreenWidth() {
return screenWidth;
} public void setScreenWidth(int screenWidth) {
this.screenWidth = screenWidth;
} public int getInitItemX() {
return initItemX;
} public void setInitItemX(int initItemX) {
this.initItemX = initItemX;
} /**
* The interface for item click callback.
*/
interface OnItemClickListener {
public boolean onItemClick(int position);
} }

CycleScrollAdapter.java

package com.example.test;

import java.util.List;

import android.app.Activity;
import android.content.Context;
import android.util.DisplayMetrics;
import android.view.View; public abstract class CycleScrollAdapter<T> { private List<T> list;
private CycleScrollView<T> mCycleScrollView;
Context mContext; /**
* Initial CycleScrollAdapter bind list to view.
*
* @param list
* The list data.
* @param cycleScrollView
* The CycleScrollView.
* @param context
* The Context.
*/
public CycleScrollAdapter(List<T> list, CycleScrollView<T> cycleScrollView,
Context context) {
this.list = list;
mContext = context;
mCycleScrollView = cycleScrollView;
mCycleScrollView.setAdapter(this);
GetScreenWidthPixels();
initView(list);
} /**
* Get screen width pixels.
*/
private void GetScreenWidthPixels() {
DisplayMetrics dm = new DisplayMetrics();
Activity a = (Activity) mContext;
a.getWindowManager().getDefaultDisplay().getMetrics(dm);
mCycleScrollView.setScreenWidth(dm.widthPixels);
} /**
* Bind list to view.
*
* @param list
* The list data.
*/
protected void initView(List<T> list) {
if (list == null || list.size() == 0) {
return;
} // Clear all view from ViewGroup at first.
mCycleScrollView.removeAllViewsInLayout(); // Loop list.
for (int i = 0; i < list.size(); i++) {
/**
* If list size more than MaxItemCount break the loop, only create
* view count is MaxItemCount.
*/
if (i == mCycleScrollView.getMaxItemCount()) {
break;
} /**
* If list size less than MaxItemCount at the last loop reLayout
* otherwise at the MaxItemCount index reLayout.
*/
if (i == list.size() - 1
|| i == mCycleScrollView.getMaxItemCount() - 1) {
mCycleScrollView.setItemX(mCycleScrollView.getInitItemX());
mCycleScrollView.setReLayout(true);
}
add(list.get(i), i);
} /**
* If list count more than MaxItemCount the view can scroll otherwise
* can not scroll.
*/
if (list.size() >= mCycleScrollView.getMaxItemCount()) {
mCycleScrollView.setCanScroll(true);
} else {
mCycleScrollView.setCanScroll(false);
} /**
* If list count more than MaxItemCount reBuild index.
*/
mCycleScrollView.createIndex();
} /**
* Get list size.
*
* @return The list size.
*/
public int getCount() {
return list.size();
} /**
* Returns the element at the specified location in this
*
* @param index
* the index of the element to return.
* @return the element at the specified location.
*/
public T get(int index) {
return list.get(index);
} /**
* Adds the specified object at the end of this and refresh view.
*
* @param t
* the object to add.
*/
public void addItem(T t) {
list.add(t);
initView(list);
} /**
* Removes the first occurrence of the specified object from this and
* refresh view.
*
* @param t
* the object to remove.
*/
public void removeItem(T t) {
list.remove(t);
initView(list);
} /**
* Add the specified view to the index.
*
* @param t
* The data to add.
* @param index
* the index.
*/
private void add(T t, int index) {
View view = getView(t);
ComputeItemSize(view);
mCycleScrollView.addView(view);
view.setTag(index);
} /**
* If item size is null compute item size.
*
* @param view
* the item view.
*/
private void ComputeItemSize(View view) {
if (mCycleScrollView.getItemWidth() == 0
|| mCycleScrollView.getItemHeight() == 0) {
int w = View.MeasureSpec.makeMeasureSpec(0,
View.MeasureSpec.UNSPECIFIED);
int h = View.MeasureSpec.makeMeasureSpec(0,
View.MeasureSpec.UNSPECIFIED);
view.measure(w, h);
int height = view.getMeasuredHeight();
int width = view.getMeasuredWidth();
mCycleScrollView.setItemHeight(height);
mCycleScrollView.setItemWidth(width);
}
} /**
* Get item view.
*
* @param t
* the data need bind to view.
* @return the view.
*/
public abstract View getView(T t); /**
* Bind the item to view.
*
* @param child
* the item view need bind.
* @param t
* the item.
*/
public abstract void bindView(View child, T t);
}

以上两个是核心类,下面是测试代码。

实现CycleScrollAdapter

AppCycleScrollAdapter.java绑定视图和应用数据

package com.example.test;

import java.util.List;

import android.content.Context;
import android.content.pm.PackageInfo;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView; public class AppCycleScrollAdapter extends CycleScrollAdapter<PackageInfo> { public AppCycleScrollAdapter(List<PackageInfo> list,
CycleScrollView<PackageInfo> cycleScrollView, Context context) {
super(list, cycleScrollView, context);
} @Override
protected void initView(List<PackageInfo> list) {
super.initView(list);
} @Override
public void bindView(View child, PackageInfo pi) {
ImageView image = (ImageView) child.findViewById(R.id.item_image);
TextView text = (TextView) child.findViewById(R.id.item_text);
image.setImageDrawable(pi.applicationInfo.loadIcon(mContext
.getPackageManager()));
text.setText(pi.applicationInfo.loadLabel(mContext.getPackageManager()));
} @Override
public View getView(PackageInfo pi) {
View view = View.inflate(mContext, R.layout.view_item, null);
// inflate APP icon view
ImageView image = (ImageView) view.findViewById(R.id.item_image);
// inflate APP name view
TextView text = (TextView) view.findViewById(R.id.item_text);
image.setImageDrawable(pi.applicationInfo.loadIcon(mContext
.getPackageManager()));
text.setText(pi.applicationInfo.loadLabel(mContext.getPackageManager()));
return view;
}
}

入口Activity

package com.example.test;

import java.util.List;

import android.app.Activity;
import android.content.pm.PackageInfo;
import android.os.Bundle;
import android.view.Menu; public class MainActivity extends Activity{ private CycleScrollView<PackageInfo> mCycleScrollView;
private AppCycleScrollAdapter mAdapter; @Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); mCycleScrollView = ((CycleScrollView<PackageInfo>) this.findViewById(R.id.cycle_scroll_view)); /**
* Get APP list and sort by update time.
*/
List<PackageInfo> list = this.getPackageManager()
.getInstalledPackages(0); mAdapter = new AppCycleScrollAdapter(list, mCycleScrollView, this); } @Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
} }

布局文件

<?xml version="1.0" encoding="utf-8"?>
<AbsoluteLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
> <ImageView
android:id="@+id/item_image"
android:layout_width="60dip"
android:layout_height="60dip"
android:layout_y="5dip"
android:layout_x="10dip"
/> <TextView
android:id="@+id/item_text"
android:layout_width="80dip"
android:layout_height="20dip"
android:layout_y="65dip"
android:layout_x="0dip"
android:gravity="center_horizontal" /> </AbsoluteLayout>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" > <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="@string/hello_world"
tools:context=".MainActivity" /> <com.example.test.CycleScrollView
android:id="@+id/cycle_scroll_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#B9000000"
/> </RelativeLayout>

android水平循环滚动控件的更多相关文章

  1. Android高级图片滚动控件,编写3D版的图片轮播器

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/17482089 大家好,好久不见了,最近由于工作特别繁忙,已经有一个多月的时间没写博 ...

  2. Android实现图片滚动控件,含页签功能,让你的应用像淘宝一样炫起来

    首先题外话,今天早上起床的时候,手滑一下把我的手机甩了出去,结果陪伴我两年半的摩托罗拉里程碑一代就这么安息了,于是我今天决定怒更一记,纪念我死去的爱机. 如果你是网购达人,你的手机上一定少不了淘宝客户 ...

  3. HorizontalScrollView水平滚动控件

    HorizontalScrollView水平滚动控件 一.简介 用法ScrollView大致相同 二.方法 1)HorizontalScrollView水平滚动控件使用方法 1.在layout布局文件 ...

  4. [android] 手机卫士自定义滚动控件

    TextView控件设置单行显示 android:singleLine=”true” 设置TextView开始的位置显示省略号,android:ellipsize=”start” 设置滚动属性,and ...

  5. Android常用酷炫控件(开源项目)github地址汇总

    转载一个很牛逼的控件收集帖... 第一部分 个性化控件(View) 主要介绍那些不错个性化的 View,包括 ListView.ActionBar.Menu.ViewPager.Gallery.Gri ...

  6. Android 常用炫酷控件(开源项目)git地址汇总

    第一部分 个性化控件(View) 主要介绍那些不错个性化的 View,包括 ListView.ActionBar.Menu.ViewPager.Gallery.GridView.ImageView.P ...

  7. 一起写一个Android图片轮播控件

    注:本文提到的Android轮播控件Demo地址: Android图片轮播控件 1. 轮播控件的组成部分 我们以知乎日报Android客户端的轮播控件为例,分析一下轮播控件的主要组成: 首先我们要有用 ...

  8. Android自定义View和控件之一-定制属于自己的UI

    照例,拿来主义.我的学习是基于下面的三篇blog.前两是基本的流程,第三篇里有比较细致的绘制相关的属性.第4篇介绍了如何减少布局层次来提高效率. 1. 教你搞定Android自定义View 2. 教你 ...

  9. 通用数据水平层级选择控件v0.70升级版使其支持jQuery v1.9.1

    升级原因:作者原来脚本支持的jquery版本太低了,查找了下资料,使得它能支持最新版本的jquery 备注说明:脚本代码源作者跟源文出处很难找,只能在此特感谢他的分享. 更新部分: 1.新版本不再支持 ...

随机推荐

  1. js判断是否为pc端或移动端

    function IsPC() { var userAgentInfo = navigator.userAgent; var Agents = new Array("Android" ...

  2. 减少可执行程序size的三个常用软件

    减少可执行程序size的三个常用软件 linux下面,直接用strip 这个命令 #:strip xxx 可以去掉编译调试信息和各种符号表,能够大大减小可执行程序size windows下面这种exe ...

  3. perl学习(10) 字符串处理函数和排序

    1.1.index Perl 查找子串第一次在大字符串中出现的地方,返回第一个字符的位置. . . my $stuff = “Howordy world!”; my $where3 = index($ ...

  4. NSUserDefaults设置bool值重新启动后bool仅仅设置丢失问题

    今天使用NSUserDefaults保存bool至重新启动后发现bool值没有保存对 NSUserDefaults *ud = [NSUserDefaults standardUserDefaults ...

  5. C# 未能加载文件或程序集“MySQLDriverCS..." 错误解决

    在解决方案的属性里,生成,里面有个目标平台,网上说的 大概也就是64位和32位的不兼容问题..试着把目标平台改为X86后竟然神奇的正常了!

  6. Java Thread 那些事

    这篇文章被压在草稿箱许久,最近公司内部的技术社区有同学贴出了几篇分享 Java线程的文章,发觉有很多概念没有讲清楚,所以花点时间继续撰写,便有了这篇博文. 本文只聚焦 JVM 层面的线程模型,不考虑和 ...

  7. element.style覆盖了我的样式!!

    原文:element.style覆盖了我的样式!! 有时候在写css时,显示效果会出现非常诡异的效果 不知道有没有遇到这种 css: #logo{ border: solid 1px blue; } ...

  8. Control.Invoke和Control.BeginInvoke

    问题的引入 下面有个简单的demo,大家一看代码就知道效果如何示例.我新建一个winform的程序,然后写入了如下代码: using System; using System.Windows.Form ...

  9. OSI七层模型基础知识及各层常见应用

       OSI Open Source Initiative(简称OSI,有译作开放源代码促进会.开放原始码组织)是一个旨在推动开源软件发展的非盈利组织.OSI参考模型(OSI/RM)的全称是开放系统互 ...

  10. unix domain IPC 进程间通信简析

    Linux系统有多种进程间通信方式,如信号.消息队列.管道等,socket是其中一种,socket使用unix domain 模式进行进程间通信 //服务端代码 #include <stdio. ...