[转载]怎么实现dedecms在首页登录会员功能_21世纪系统网

mikel阅读(874)

[转载]怎么实现dedecms在首页登录会员功能_21世纪系统网.
必须引入的两个JS文件:

<script src="{dede:global.cfg_cmsurl/}/include/dedeajax2.js" type="text/javascript" language="javascript"></script><script type="text/javascript" language="javascript">// <![CDATA[
      
function CheckLogin(){         
var taget_obj = document.getElementById('_userlogin');        
 myajax = new DedeAjax(taget_obj,false,false,'','','');         
 myajax.SendGet2("{dede:global.cfg_cmspath/}/member/ajax_loginsta.php");        
 DedeXHTTP = null;      
  }    
// ]]></script>

登录后的显示内容在 ajax_loginsta.php里修改:

在需要判断是否登录的位置赋予一个id名为_userlogin的div或者span都行,然后打开/member/ajax_loginsta.php进行相应的如果登录了该显示什么样式图标的设置。

最后在这段代码下面加上这局js代码,用来判断页面是否已经登录了:

<script type="text/javascript" language="javascript">// <![CDATA[
CheckLogin();
// ]]></script>

心得体会:

Dedecms的东西都是封装好的,只需要一步一步跟着走就能找到你所需要修改的东西,进而实现dedecms的二次开发(所有东西都可以用原有的模版文件进行套用)。
自定义定义网站登录框的样式方式:

<!-- 登录注册框开始 -->
<div id="_userlogin">
<a href="/member/index_do.php?fmdo=user&dopost=regnew" style="color: #FF9900;">注册</a> | <a href="/member/login.php" style="color: #FF9900;">登录</a> <a href="{dede:global.cfg_memberurl/}/resetpassword.php">找回密码?</a> 
</div>
<script language="javascript" type="text/javascript">CheckLogin();</script>
<!-- 登录注册框结束 -->

[转载]织梦DedeCMS会员登录状态调用与样式修改方法_21世纪系统网

mikel阅读(847)

[转载]织梦DedeCMS会员登录状态调用与样式修改方法_21世纪系统网.
一、横向样式

1、实现过程

第一步:我们首先新建一个空白的默认首页模板(通常为index.htm),并设置为启用状态,然后掏空里面的所有代码。

第二步:然后在区域内加入以下代码:

<script src="{dede:global.cfg_cmsurl/}/include/dedeajax2.js" type="text/javascript" language="javascript"></script><script type="text/javascript" language="javascript">// <![CDATA[
function CheckLogin(){    var taget_obj = document.getElementById('_userlogin');    myajax = new DedeAjax(taget_obj,false,false,'','','');    myajax.SendGet2("{dede:global.cfg_cmspath/}/member/ajax_loginsta.php");    DedeXHTTP = null;    }
// ]]></script>

第三步:然后再在区域增加如下代码:

<div id="_userlogin"><form action="{dede:global.cfg_memberurl/}/index_do.php" method="POST" name="userlogin"><input name="fmdo" type="hidden" value="login" />

<input name="dopost" type="hidden" value="login" />

<input name="keeptime" type="hidden" value="604800" />
<ul>
	<li><label>用户名:</label> <input class="text" style="width: 80px;" name="userid" type="text" /></li>
	<li><label>密 码:</label> <input class="text" style="width: 80px;" name="pwd" type="password" /></li>
	<li><label>验证码:</label><input class="text" style="width: 40px;" name="vdcode" type="text" /> <img id="vdimgck" style="cursor: pointer; margin-left: 0px;" src="../include/vdimgck.php" alt="看不清?点击更换" align="absmiddle" /></li>
	<li><button class="btn-1" type="submit">登录</button> <a href="{dede:global.cfg_memberurl/}/index_do.php?fmdo=user&amp;dopost=regnew">注册帐号</a> <a href="{dede:global.cfg_memberurl/}/resetpassword.php">忘记密码?</a></li>
</ul>
</form></div>
<script type="text/javascript" language="javascript">// <![CDATA[
CheckLogin();
// ]]></script>

第四步:代码添加完毕,我们生成首页或者直接浏览动态首页看看效果:

织梦DedeCMS会员登录状态调用与样式修改方法

第五步:我们输入正确的账号密码,回到首页的效果图:

织梦DedeCMS会员登录状态调用与样式修改方法

到此,我们的横向登陆样式就制作完毕了。

但是很明显,登陆后的样式非常丑陋,我们应该美化一下,但在美化之前我们应该要来了解一下代码中的含义。

2、代码解释

所谓的代码解释就是要让大家能够看得懂,所以大家可以看一下整个页面的注释版代码:


&nbsp;

&nbsp;

&nbsp;

首页登陆样式测试

<script src="{dede:global.cfg_cmsurl/}/include/dedeajax2.js" type="text/javascript" language="javascript"></script><!--这段是显示整个效果必须要存在的ajax框架--><script type="text/javascript" language="javascript">// <![CDATA[
function CheckLogin(){ //判断是否登陆的函数   

var taget_obj = document.getElementById('_userlogin'); //登陆后动态加载的区块,也就是<body>区域的id="_userlogin"的所有内容   

myajax = new DedeAjax(taget_obj,false,false,'','','');   

myajax.SendGet2("{dede:global.cfg_cmspath/}/member/ajax_loginsta.php"); //登陆后的要显示的具体内容   

DedeXHTTP = null;   

}
// ]]></script>

&nbsp;

*****************************************

&nbsp;
<div id="_userlogin">

<!--动态显示的内容区块,ID值必须与上面的document.getElementById('_userlogin') 中 的_userlogin保持一致-->

<form action="{dede:global.cfg_memberurl/}/index_do.php" method="POST" name="userlogin"><!--登陆提交的处理页面-->

<input name="fmdo" type="hidden" value="login" /><!--定义操作为login-->

<input name="dopost" type="hidden" value="login" /><!--定义操作为login-->

<input name="keeptime" type="hidden" value="604800" /><!--记住登陆状态的时间,单位秒-->
<ul>
	<li><label>用户名:</label> <input class="text" style="width: 80px;" name="userid" type="text" /><!--用户名--></li>
	<li><label>密 码:</label> <input class="text" style="width: 80px;" name="pwd" type="password" /><!--密码--></li>
	<li><label>验证码:</label><input class="text" style="width: 40px;" name="vdcode" type="text" /> <img id="vdimgck" style="cursor: pointer; margin-left: 0px;" src="../include/vdimgck.php" alt="看不清?点击更换" align="absmiddle" /></li>
	<li><button class="btn-1" type="submit">登录</button></li>
</ul>
</form></div>
<script type="text/javascript" language="javascript">// <![CDATA[
CheckLogin();
// ]]></script><!--本函数必须加载,用于获取上面的function CheckLogin()函数-->

通过上面的查看,我们已经知道要美化这个样式,只需要修改 /member/ajax_loginsta.php 文件的代码即可。

我们打开这个文件,将里面的代码全部替换为如下代码:

<!--?php    require_once(dirname(__FILE__)."/config.php");    AjaxHead();    if($myurl == '')    {    exit('');    }    $uid  = $cfg_ml--->M_LoginID;

!$cfg_ml-&gt;fields['face'] &amp;&amp; $face = ($cfg_ml-&gt;fields['sex'] == '女')? 'dfgirl' : 'dfboy';

$facepic = emptyempty($face)? $cfg_ml-&gt;fields['face'] : $GLOBALS['cfg_memberurl'].'/templets/images/'.$face.'.png';

?&gt;

你好:<!--?php echo $cfg_ml--->M_UserName; ?&gt;,欢迎登录!<a href="&lt;?php echo $cfg_memberurl; ?&gt;/guestbook_admin.php">我的留言</a> | <a href="&lt;?php echo $cfg_memberurl; ?&gt;/mystow.php">我的收藏</a> | <a href="&lt;?php echo $cfg_memberurl; ?&gt;/index.php">会员中心</a> | <a href="&lt;?php echo $cfg_memberurl; ?&gt;/edit_fullinfo.php">修改资料</a> | <a href="&lt;?php echo $myurl;?&gt;">空间</a> | <a href="&lt;?php echo $cfg_memberurl; ?&gt;/index_do.php?fmdo=login&amp;dopost=exit">退出登录</a>

我们也顺道来看一下修改后的效果:

织梦DedeCMS会员登录状态调用与样式修改方法

怎么样?大家知道应该如何来制作这个效果了吧。好了,我们再来看看竖向的登录框。

二、竖向登陆

(责任编辑:模板天下)

通过横向登陆的示例,其实我们很容易理解。要做一个竖向登陆的这个效果,只需要将登陆前后的样式分别修改一下即可,不需要修改其它任何功能文件。

这是我修改的竖向登陆的登录前样式:


&nbsp;

&nbsp;

&nbsp;

首页登陆样式测试

<script src="{dede:global.cfg_cmsurl/}/include/dedeajax2.js" type="text/javascript" language="javascript"></script><!--这段是显示整个效果必须要存在的ajax框架--><script type="text/javascript" language="javascript">// <![CDATA[
  

function CheckLogin(){ //判断是否登陆的函数   

var taget_obj = document.getElementById('_userlogin'); //登陆后动态加载的区块,也就是<body>区域的id="_userlogin"的所有内容   

myajax = new DedeAjax(taget_obj,false,false,'','','');   

myajax.SendGet2("{dede:global.cfg_cmspath/}/member/ajax_loginsta.php"); //登陆后的要显示的具体内容   

DedeXHTTP = null;   

}   
// ]]></script>

&nbsp;

&nbsp;
<div id="_userlogin">

<!--动态显示的内容区块,ID值必须与上面的document.getElementById('_userlogin') 中 的_userlogin保持一致-->

<form action="{dede:global.cfg_memberurl/}/index_do.php" method="POST" name="userlogin"><!--登陆提交的处理页面-->

<input name="fmdo" type="hidden" value="login" /><!--定义操作为login-->

<input name="dopost" type="hidden" value="login" /><!--定义操作为login-->

<input name="keeptime" type="hidden" value="604800" /><!--记住登陆状态的时间,单位秒-->
<ul>
	<li><label>用户名:</label><input class="text" style="width: 100px;" name="userid" type="text" /><!--用户名--></li>
	<li><label>密 码:</label> <input class="text" style="width: 100px;" name="pwd" type="password" /><!--密码--></li>
	<li><label>验证码:</label><input class="text" style="width: 40px;" name="vdcode" type="text" /> <img id="vdimgck" style="cursor: pointer; margin-left: 0px;" src="../include/vdimgck.php" alt="看不清?点击更换" align="absmiddle" /></li>
	<li><button class="btn-1" type="submit">登录</button> <a href="{dede:global.cfg_memberurl/}/index_do.php?fmdo=user&amp;dopost=regnew">注册帐号</a> <a href="{dede:global.cfg_memberurl/}/resetpassword.php">忘记密码?</a></li>
</ul>
</form></div>
<script type="text/javascript" language="javascript">// <![CDATA[
CheckLogin();
// ]]></script><!--本函数必须加载,用于获取上面的function CheckLogin()函数-->

&nbsp;

好,接下来我们看看效果:

织梦DedeCMS会员登录状态调用与样式修改方法

登陆后的显示样式我们用织梦(DedeCMS)自带的,来看看效果:

织梦DedeCMS会员登录状态调用与样式修改方法

这些年用过的主机

mikel阅读(903)

1.台湾的vps 一直用得是后路哥的主机,淘宝上买的,还算稳定,价格也公道

T2VTqRXpJXXXXXXXXX_!!13569634

2.阿里云的不少备案客户在用,感觉还行,速度和备案都挺省事儿的,就是价格对于屌丝来说小贵,不过性能稳定性对得起这价格

TB11EDCHXXXXXX8XpXXtKXbFXXX

3.用过康盛的主机,香港的还不错,就是价格贵,稳定性好,对于做论坛的朋友应该不错的选择

QQ截图20150205100340
4.狗爹(Goddady)的国外算是有名了,不过国内频频封ip,不得已才迁出到了其他主机商,价格上便宜没的说,就是拗不过天朝没办法,做外贸站的推荐

5. 恒创科技(henghost.com)的主机还算不错,香港主机稳定性不错,总是有特价活动,客服也给力

6.其他的主机也用了不少,不过总结一句一分钱一分货,别图便宜吃了大亏,网站稳定和速度该下下血本儿,毕竟靠着它吃饭呢,好不容易流量上来,没法儿访问了,那就得不偿失了!

 

支付宝红包口令再掀红包狂潮 微信还hold住吗?!

mikel阅读(899)

从微博红包引发的支付宝绑定微博开始,这临近年关的时候,网络上红包满天飞就开始了,微信久久没有动作,不知道是否在酝酿着什么,还是有意无意得回避着支付宝的锋芒,默默的封了支付宝红包分享到朋友圈的连接后,支付宝也封了微信跳转到淘宝的链接。不仅娱乐圈乱,看来互联网也是够乱的。

支付宝这不又推出了“红包口令”功能,这下发钱都是秘密的了,知道口令的来抢,似乎更人性化了,不过让我这种数字不敏感的人很为难的记下那么多的红包口令,还得来回跳转手机窗口,实在是不如微信红包来得简单,不知道是哪位大神研究出来的,有没有想过我这种人的感受?!太任性了!

QQ图片20150204165110

红包这种模式疯行,就在于里面是真金白银得在那流动,不像那些有的没的的什么抽奖、大转盘之类的放一些看上去很好的奖品,结果人们都已经麻木了,不放肾六就没参与的想法,这下有了红包真金白银得抽,直接提现到支付宝,拿多少全看运气了,刺激!好玩!一下出现了很多红包专业户,流窜在各大平台之间,只要有红包就有他们的身影,发红包也同样是他们在推波助澜的发!

 

牛逼的模式不需要解释,大家都懂。就像嘎嘎客,没有啥难度,关注就能得自己的二维码,然后推广人关注,商城下单购买就拿佣金!多好!现在人都闲麻烦,也越来越没耐心了!不如来直接的,化繁为简!

gagake

[转载]一款Android开源的下拉刷新动画 - 有梦想的小人物 - 博客园

mikel阅读(1289)

[转载]一款Android开源的下拉刷新动画 – 有梦想的小人物 – 博客园.

无意间在GitHub看到的,就Down了下来。但是作者是用AndroidStudio开发的,这边移动Eclipse供小伙伴们下载使用。

截图

这么好的东西因为字数不够不让分享,得了,贴段代码吧

package com.example.pullrefersh;

import android.content.Context;
import android.content.res.TypedArray;
import android.support.v4.view.MotionEventCompat;
import android.support.v4.view.ViewCompat;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
import android.view.animation.Transformation;
import android.widget.AbsListView;
import android.widget.ImageView;

import java.security.InvalidParameterException;

import refresh_view.BaseRefreshView;
import refresh_view.SunRefreshView;
import util.Utils;

public class PullToRefreshView extends ViewGroup {

private static final int DRAG_MAX_DISTANCE = 120;
private static final float DRAG_RATE = .5f;
private static final float DECELERATE_INTERPOLATION_FACTOR = 2f;

public static final int STYLE_SUN = 0;
public static final int STYLE_JET = 1;
public static final int MAX_OFFSET_ANIMATION_DURATION = 700;

private static final int INVALID_POINTER = -1;

private View mTarget;
private ImageView mRefreshView;
private Interpolator mDecelerateInterpolator;
private int mTouchSlop;
private int mTotalDragDistance;
private BaseRefreshView mBaseRefreshView;
private float mCurrentDragPercent;
private int mCurrentOffsetTop;
private boolean mRefreshing;
private int mActivePointerId;
private boolean mIsBeingDragged;
private float mInitialMotionY;
private int mFrom;
private float mFromDragPercent;
private boolean mNotify;
private OnRefreshListener mListener;

public PullToRefreshView(Context context) {
this(context, null);
}

public PullToRefreshView(Context context, AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RefreshView);
final int type = a.getInteger(R.styleable.RefreshView_type, STYLE_SUN);
a.recycle();

mDecelerateInterpolator = new DecelerateInterpolator(DECELERATE_INTERPOLATION_FACTOR);
mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
mTotalDragDistance = Utils.convertDpToPixel(context, DRAG_MAX_DISTANCE);

mRefreshView = new ImageView(context);

setRefreshStyle(type);

addView(mRefreshView);

setWillNotDraw(false);
// ViewCompat.setChildrenDrawingOrderEnabled(this, true);
}

public void setRefreshStyle(int type) {
setRefreshing(false);
switch (type) {
case STYLE_SUN:
mBaseRefreshView = new SunRefreshView(getContext(), this);
break;
case STYLE_JET:
// TODO
default:
throw new InvalidParameterException("Type does not exist");
}
mRefreshView.setImageDrawable(mBaseRefreshView);
}

public int getTotalDragDistance() {
return mTotalDragDistance;
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);

ensureTarget();
if (mTarget == null)
return;

widthMeasureSpec = MeasureSpec.makeMeasureSpec(getMeasuredWidth() - getPaddingRight() - getPaddingLeft(), MeasureSpec.EXACTLY);
heightMeasureSpec = MeasureSpec.makeMeasureSpec(getMeasuredHeight() - getPaddingTop() - getPaddingBottom(), MeasureSpec.EXACTLY);
mTarget.measure(widthMeasureSpec, heightMeasureSpec);
mRefreshView.measure(widthMeasureSpec, heightMeasureSpec);
}

private void ensureTarget() {
if (mTarget != null)
return;
if (getChildCount() &gt; 0) {
for (int i = 0; i &lt; getChildCount(); i++) { View child = getChildAt(i); if (child != mRefreshView) mTarget = child; } } } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { if (!isEnabled() || canChildScrollUp() || mRefreshing) { return false; } final int action = MotionEventCompat.getActionMasked(ev); switch (action) { case MotionEvent.ACTION_DOWN: setTargetOffsetTop(0, true); mActivePointerId = MotionEventCompat.getPointerId(ev, 0); mIsBeingDragged = false; final float initialMotionY = getMotionEventY(ev, mActivePointerId); if (initialMotionY == -1) { return false; } mInitialMotionY = initialMotionY; break; case MotionEvent.ACTION_MOVE: if (mActivePointerId == INVALID_POINTER) { return false; } final float y = getMotionEventY(ev, mActivePointerId); if (y == -1) { return false; } final float yDiff = y - mInitialMotionY; if (yDiff &gt; mTouchSlop &amp;&amp; !mIsBeingDragged) {
mIsBeingDragged = true;
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
mIsBeingDragged = false;
mActivePointerId = INVALID_POINTER;
break;
case MotionEventCompat.ACTION_POINTER_UP:
onSecondaryPointerUp(ev);
break;
}

return mIsBeingDragged;
}

@Override
public boolean onTouchEvent(MotionEvent ev) {

if (!mIsBeingDragged) {
return super.onTouchEvent(ev);
}

final int action = MotionEventCompat.getActionMasked(ev);

switch (action) {
case MotionEvent.ACTION_MOVE: {
final int pointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId);
if (pointerIndex &lt; 0) {
return false;
}

final float y = MotionEventCompat.getY(ev, pointerIndex);
final float yDiff = y - mInitialMotionY;
final float scrollTop = yDiff * DRAG_RATE;
mCurrentDragPercent = scrollTop / mTotalDragDistance;
if (mCurrentDragPercent &lt; 0) { return false; } float boundedDragPercent = Math.min(1f, Math.abs(mCurrentDragPercent)); float extraOS = Math.abs(scrollTop) - mTotalDragDistance; float slingshotDist = mTotalDragDistance; float tensionSlingshotPercent = Math.max(0, Math.min(extraOS, slingshotDist * 2) / slingshotDist); float tensionPercent = (float) ((tensionSlingshotPercent / 4) - Math.pow( (tensionSlingshotPercent / 4), 2)) * 2f; float extraMove = (slingshotDist) * tensionPercent / 2; int targetY = (int) ((slingshotDist * boundedDragPercent) + extraMove); mBaseRefreshView.setPercent(mCurrentDragPercent, true); setTargetOffsetTop(targetY - mCurrentOffsetTop, true); break; } case MotionEventCompat.ACTION_POINTER_DOWN: final int index = MotionEventCompat.getActionIndex(ev); mActivePointerId = MotionEventCompat.getPointerId(ev, index); break; case MotionEventCompat.ACTION_POINTER_UP: onSecondaryPointerUp(ev); break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: { if (mActivePointerId == INVALID_POINTER) { return false; } final int pointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId); final float y = MotionEventCompat.getY(ev, pointerIndex); final float overScrollTop = (y - mInitialMotionY) * DRAG_RATE; mIsBeingDragged = false; if (overScrollTop &gt; mTotalDragDistance) {
setRefreshing(true, true);
} else {
mRefreshing = false;
animateOffsetToStartPosition();
}
mActivePointerId = INVALID_POINTER;
return false;
}
}

return true;
}

private void animateOffsetToStartPosition() {
mFrom = mCurrentOffsetTop;
mFromDragPercent = mCurrentDragPercent;
long animationDuration = Math.abs((long) (MAX_OFFSET_ANIMATION_DURATION * mFromDragPercent));

mAnimateToStartPosition.reset();
mAnimateToStartPosition.setDuration(animationDuration);
mAnimateToStartPosition.setInterpolator(mDecelerateInterpolator);
mAnimateToStartPosition.setAnimationListener(mToStartListener);
mRefreshView.clearAnimation();
mRefreshView.startAnimation(mAnimateToStartPosition);
}

private void animateOffsetToCorrectPosition() {
mFrom = mCurrentOffsetTop;
mFromDragPercent = mCurrentDragPercent;

mAnimateToCorrectPosition.reset();
mAnimateToCorrectPosition.setDuration(MAX_OFFSET_ANIMATION_DURATION);
mAnimateToCorrectPosition.setInterpolator(mDecelerateInterpolator);
mRefreshView.clearAnimation();
mRefreshView.startAnimation(mAnimateToCorrectPosition);

if (mRefreshing) {
mBaseRefreshView.start();
if (mNotify) {
if (mListener != null) {
mListener.onRefresh();
}
}
} else {
mBaseRefreshView.stop();
animateOffsetToStartPosition();
}
mCurrentOffsetTop = mTarget.getTop();
}

private final Animation mAnimateToStartPosition = new Animation() {
@Override
public void applyTransformation(float interpolatedTime, Transformation t) {
moveToStart(interpolatedTime);
}
};

private final Animation mAnimateToCorrectPosition = new Animation() {
@Override
public void applyTransformation(float interpolatedTime, Transformation t) {
int targetTop;
int endTarget = mTotalDragDistance;
targetTop = (mFrom + (int) ((endTarget - mFrom) * interpolatedTime));
int offset = targetTop - mTarget.getTop();

mCurrentDragPercent = mFromDragPercent - (mFromDragPercent - 1.0f) * interpolatedTime;
mBaseRefreshView.setPercent(mCurrentDragPercent, false);

setTargetOffsetTop(offset, false /* requires update */);
}
};

private void moveToStart(float interpolatedTime) {
int targetTop = mFrom - (int) (mFrom * interpolatedTime);
float targetPercent = mFromDragPercent * (1.0f - interpolatedTime);
int offset = targetTop - mTarget.getTop();

mCurrentDragPercent = targetPercent;
mBaseRefreshView.setPercent(mCurrentDragPercent, true);
setTargetOffsetTop(offset, false);
}

public void setRefreshing(boolean refreshing) {
if (mRefreshing != refreshing) {
setRefreshing(refreshing, false /* notify */);
}
}

private void setRefreshing(boolean refreshing, final boolean notify) {
if (mRefreshing != refreshing) {
mNotify = notify;
ensureTarget();
mRefreshing = refreshing;
if (mRefreshing) {
mBaseRefreshView.setPercent(1f, true);
animateOffsetToCorrectPosition();
} else {
animateOffsetToStartPosition();
}
}
}

private Animation.AnimationListener mToStartListener = new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}

@Override
public void onAnimationRepeat(Animation animation) {
}

@Override
public void onAnimationEnd(Animation animation) {
mBaseRefreshView.stop();
mCurrentOffsetTop = mTarget.getTop();
}
};

private void onSecondaryPointerUp(MotionEvent ev) {
final int pointerIndex = MotionEventCompat.getActionIndex(ev);
final int pointerId = MotionEventCompat.getPointerId(ev, pointerIndex);
if (pointerId == mActivePointerId) {
final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
mActivePointerId = MotionEventCompat.getPointerId(ev, newPointerIndex);
}
}

private float getMotionEventY(MotionEvent ev, int activePointerId) {
final int index = MotionEventCompat.findPointerIndex(ev, activePointerId);
if (index &lt; 0) {
return -1;
}
return MotionEventCompat.getY(ev, index);
}

private void setTargetOffsetTop(int offset, boolean requiresUpdate) {
mTarget.offsetTopAndBottom(offset);
mBaseRefreshView.offsetTopAndBottom(offset);
mCurrentOffsetTop = mTarget.getTop();
if (requiresUpdate &amp;&amp; android.os.Build.VERSION.SDK_INT &lt; 11) {
invalidate();
}
}

private boolean canChildScrollUp() {
if (android.os.Build.VERSION.SDK_INT &lt; 14) { if (mTarget instanceof AbsListView) { final AbsListView absListView = (AbsListView) mTarget; return absListView.getChildCount() &gt; 0
&amp;&amp; (absListView.getFirstVisiblePosition() &gt; 0 || absListView.getChildAt(0)
.getTop() &lt; absListView.getPaddingTop()); } else { return mTarget.getScrollY() &gt; 0;
}
} else {
return ViewCompat.canScrollVertically(mTarget, -1);
}
}

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {

ensureTarget();
if (mTarget == null)
return;

int height = getMeasuredHeight();
int width = getMeasuredWidth();
int left = getPaddingLeft();
int top = getPaddingTop();
int right = getPaddingRight();
int bottom = getPaddingBottom();

mTarget.layout(left, top + mCurrentOffsetTop, left + width - right, top + height - bottom + mCurrentOffsetTop);
mRefreshView.layout(left, top, left + width - right, top + height - bottom);
}

public void setOnRefreshListener(OnRefreshListener listener) {
mListener = listener;
}

public static interface OnRefreshListener {
public void onRefresh();
}

}

下载地址:http://download.csdn.net/detail/lj419855402/8421179

微信的大数据之路还有多远

mikel阅读(894)

最近微信的动作很大,从朋友圈的广告就可以看出,微信耐不住寂寞了,收网时候到了。

不过从微信的动作也可以看出微信在大数据分析上的努力,宝马、vivo、可口可乐的广告谁看了?!都是通过大数据分析定向投放的,于是一时间看到宝马的广告就是高富帅的言论风行,那些只看到可口可乐的屌丝不得不暗自神伤,连微信都被鄙视,没法活了!

psb

微信为什么要用大数据?可见微信掌握的数据不亚于阿里了,最近的抢红包盛行的时候,微信又封锁了支付宝分享到微信的接口,不说什么竞争了,就说这两家大数据公司的数据量不分上下,微信每天的数据量就是惊人,淘宝又何尝不是?不过两者的数据侧重点不同,微信更偏向于生活娱乐数据,更加贴近人的正常生活,阿里的数据则更倾向于商业数据,贴近于人的消费行为,如果两家公司合并,那我们的生活数据彻底裸奔了,这种宝马、可口可乐的定向广告会更加精准的,因为你在数据面前的所有习惯和行为都是透明的。

支付宝的芝麻信用也是打得大数据牌,由此可见未来并不是移动互联网的时代,而是大数据的时代,那如何保证数据的安全性和真实性就无疑是焦点了。从微信公众平台的一系列措施让人看到公开数据只是迟早的事儿,至于公开到什么程度,那就要看微信的态度了。

[转载]Android应用系列:手把手教你做一个小米通讯录(附图附源码) - enjoy风铃 - 博客园

mikel阅读(1049)

[转载]Android应用系列:手把手教你做一个小米通讯录(附图附源码) – enjoy风铃 – 博客园.

前言

最近心血来潮,突然想搞点仿制品玩玩,很不幸小米成为我苦逼的第一个试验品。既然雷布斯的MIUI挺受欢迎的(本人就是其的屌丝用户),所以就 拿其中的一些小功能做一些小demo来玩玩。小米的通讯录大家估计用过小米的都清楚是啥子样的,没用过小米的也别着急,瞧瞧我的demo,起码也有七八分 相似滴。先上图看效果

我是图:

PS:吐槽一下,博客园上个图真难,所以搞了个短点的gif上才没失败。。。。唉。。。

在这里仅仅是实现了逻辑交互的效果,并没有点击打电话的功能,因为也不难就懒得加了。。。

分析

我们说说这个东西主要的实现功能点在哪些?

1、输入数据按首字母排序

2、查询框输入时快速更改数据显示

3、右端首字母跟随数据列表位置高亮显示

4、滑动时,出现数据第一个字提示

解决方案

1、输入数据按首字母排序

这个怎么办呢?毕竟一个Android小小的一个软件不可用把整个汉字拼音转换库放进去对吧,如果真的放进去,你觉得这样用户会买你的帐,对不 起你的APP太大啦;所以Stop这个想法!但是我们换一个思路,既然汉字在计算机中的是以编码的存放的,我们是不是可以再编码这里面做点文章。就以 GB2312来说,里面的汉字是按字典序排列的,就是越前面其声母越靠前,例如第一个汉字编码代表的就是“啊”这个字,那好办了,我们只要把各个首字母的 编码获取区间,然后对于任何一个汉字,判断其是否在相对应区间中即可获取该汉字的首字母。但是但是,对于多音字这个东西,大家当我没说好吧???

附核心源码:

/**
* GetPYUntl工具类提供根据汉字获取首字母的功能
* 仅支持GB2312简体汉字
*/
public class GetPYUntl {

//简体中文的编码范围从B0A1(45217)一直到F7FE(63486)
private static final int BEGIN = 45217;
private static final int END = 63486;

//按照声 母表示,这个表是在GB2312中的出现的第一个汉字,也就是说“啊”是代表首字母a的第一个汉字
//i, u, v都不做声母, 自定规则跟随前面的字母
//最后保持空格
private static final char[] charTable = new char[]{'啊', '芭', '擦', '搭', '蛾', '发',
'噶', '哈', '哈', '击', '喀', '垃', '妈',
'拿', '哦', '啪', '期', '然', '撒', '塌',
'塌', '塌', '挖', '昔', '压', '匝'};

//对应首字母区间表
private static final char[] initialtable = new char[]{'A', 'B', 'C', 'D', 'E', 'F', 'G',
'H', 'H', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T', 'T', 'T', 'W', 'X', 'Y',
'Z'};

//二十六个字母区间对应二十七个端点
//GB2312码汉字区间十进制表示
private static int[] table = new int[27];

//工具类初始化代码块,进行初始化操作
static{
for(int i = 0; i &lt; 26; i++){
table[i] = getGBValue(charTable[i]);//得到GB2312码的首字母区间端点表,十进制。
}
table[26] = END;//区间表的结尾数值
}

/**
* 根据汉字c获取其对应的编码
* 将一个汉字(GB2312)转换为十进制表示
*/
private static int getGBValue(char c) {
String str = c + "";
try{
byte[] bytes = str.getBytes("GB2312");
if (bytes.length &lt; 2){
return 0;
}
return (bytes[0] &lt;&lt; 8 &amp; 0xff00) + (bytes[1] &amp; 0xff); } catch (Exception e){ return 0; } } //----------------------对外调用方法区---------------------------------------// /** * 根据输入的单汉字,返回首字母 * @param ch 所需要查询的汉字 * @return 返回对应输入汉字的首字母 */ public static char getFristWord(char ch){ //ch为英文字符,小写转为大写,大写直接返回 if(ch &gt;= 'a' &amp;&amp; ch &lt;= 'z'){ return (char)(ch - 'a' + 'A'); } if(ch &gt;= 'A' &amp;&amp; ch &lt;= 'Z'){
return ch;
}
//若为汉字,获取其区间值,并判断是否在码表的范围中
//若不是,返回&amp;
//若是,在码表对其进行判断
int gb = getGBValue(ch);

if(gb &lt; BEGIN || gb &gt; END){
return '&amp;';
}
int i;
for(i = 0; i &lt; 26; i++){//判断匹配码表区间,匹配到就break,判断区间形如“[,)” if(gb &gt;= table[i] &amp;&amp; gb &lt; table[i+1]){
break;
}
}
if(gb == END){//补齐GB2312区间最右端,就是首字母编码值为END
i = 25;
}
return initialtable[i];//在码表区间中,返回首字母
}

/**
* 根据输入的汉字字符串,返回首字母字符串,内部机制依赖调用 getFristWord(char ch)方法。
* @param str 所需要查询的汉字字符串
* @return 返回对应输入汉字字符串的首字母字符串
*/
public static String getFristWord(String str){
String reslut = "";
if(str != null || str != ""){//容错操作,校验输入的字符串
int length = str.length();
for(int i = 0; i &lt; length; i++){//分别对str的各个字符进行取首字母操作
reslut += getFristWord(str.charAt(i));
}
}
return reslut;
}

/**
* 提供两个字符串,根据其首字母字符串的排列顺序
* @param str1
* @param str2
* @return true:str1位于str2前面,false:str1位于str2后面
*/
public static int Compare(String str1, String str2){
String cstr1 = getFristWord(str1);
String cstr2 = getFristWord(str2);
return cstr1.compareTo(cstr2);
}
}

2、查询框输入时快速更改数据显示

这个实现比较简单,主要是用到TextWatcher这个类来监听EditText的内容变化,如果我们在输入查询内容,TextWatcher会监听EditText的状态改变,调用onTextChanged()方法响应。

@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
dealData.clear();//清空上次的query查询处理后的数据,用于加载新一次数据
if(data != null &amp;&amp; !"".equals(s.toString())){//query有内容,显示根据query处理后的数据
for(int i = 0; i &lt; data.size(); i++){//编译显示内容,将符合的数据收集到dealData
String str = data.get(i);
//判断s是否为str的子字符串,如果是,则是需要收集的数据,s为query当前输入的内容
boolean find = str.contains(s.toString());
if(find){
dealData.add(str);
}
}
//更新listView的数据源
adapter.setData(dealData, s.toString());
//刷新listView
list.invalidateViews();
}
else{//数据集合为空,或者不存在查询的query请求
adapter.setData(data, s.toString());
list.invalidateViews();//刷新listView为初始状态
}
}

但是!这个东西实现的最重要逻辑并不是TextWatcher的代码,而是我们重写的BaseAdapter里面的getView方法。因为我们要根据查询内容高亮显示字体,所以我们的ListView的item对应的View需要着重处理,但是这样会引入大量的View,估计教育我们要记得重用View,所以我在getView里面也大量用重用思想,减少资源占用率。

由于逻辑比较复杂,说以简略说说实现思路吧:BaseAdapter会根据是否有查询请求的接入,如果没有查询请求则是显示全部数据,那么我们会在每一个convertView里面add一个TextView的实例,显示全部内容。如果有查询请求,BaseAdapter会整理要显示的数据,然后在convertView里面add若干个TextView,每一个TextView将会只显示一个字,在对应需要高亮的TextView会进行设置字体颜色。但是这样会导致很多TextView的存在,所以我们在每一个convertView里面会设置缓存缓存这些TextView的引用,如果下次复用时直接从Tag中取得TextView进行处理后add到convertView里面显示,然后清理掉多余的缓存。如果你看懵了不要紧,注释非常详细,可以过一下代码。

核心代码:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
List cache = null;
//进行convertView的复用,如果第一次使用,则实例化该View
if(convertView == null){
convertView = inflater.inflate(R.layout.mark_list_item, null, false);
//申请一个缓冲cache用于保存其子TextView的引用
cache = new ArrayList();

TextView tv = null;
if(query == null || "".equals(query)){//如果query为null,或者为空字符串,则直接加载
tv = new TextView(context);
tv.setText(data.get(position));//将其整个字符串设置到TextView里面,而不单字加载
setTextParmas(tv);
((LinearLayout)convertView).addView(tv);//加载到convertView节点下
cache.add(tv);//缓存集合中保存tv的引用,便于下次复用该TextView
}
else{//query不为null,其有query内容,我们需要将该查询内容对于的字符高亮显示
//将显示内容的字符串拆分为字符数组,用于单字加载
char[] words = data.get(position).toCharArray();
for(int i = 0; i &lt; words.length; i++){
tv = new TextView(context);
tv.setText(words[i]+"");//单字加载,即一个字用一个TextView显示
setTextParmas(tv);
//查询是否在query的内容之中,如果为是则将该TextView高亮显示
for(char c : query){
if(c == words[i])
tv.setTextColor(Color.RED);
}
((LinearLayout)convertView).addView(tv);
cache.add(tv);
}
}
}
else{//如果不是第一次使用,则该convertView可以被复用
cache = (List) convertView.getTag();//获取缓存cache集合
TextView tv;
int usingSize = 0;//记录当前convertView所有使用的TextView个数
int length = cache.size();
if(query == null || "".equals(query)){//如果query为null,或者为空字符串,则直接加载
if(length &gt; 0){//检测cache是否存在可复用的View
tv = cache.get(0);//取首个TextView复用
tv.setTextColor(Color.GRAY);
}
else{//如果没有可复用的TextView,实例化一个TextView并加入缓存中
tv = new TextView(context);
setTextParmas(tv);
((LinearLayout)convertView).addView(tv);
cache.add(tv);
}
tv.setText(data.get(position));
usingSize++;
}
else{//query不为null,其有query内容,我们需要将该查询内容对于的字符高亮显示
//将显示内容的字符串拆分为字符数组,用于单字加载
char[] words = data.get(position).toCharArray();
for(int i = 0; i &lt; words.length; i++){
if(i &lt; length){//获取第i个缓存的TextView
tv = cache.get(i);
tv.setTextColor(Color.GRAY);
}
else{//如果已经没有缓存TextView可获取了
tv = new TextView(context);
setTextParmas(tv);
((LinearLayout)convertView).addView(tv);
cache.add(tv);
}
//查询是否在query的内容之中,如果为是则将该TextView高亮显示
for(char c : query){
if(c == words[i])
tv.setTextColor(Color.RED);
}
tv.setText(words[i]+"");//单字加载,即一个字用一个TextView显示
usingSize++;
}
}
clearCache(convertView, cache, usingSize);
}
convertView.setTag(cache);//保存缓存cache集合
firstWord.add(position, cache.get(0).getText().toString().charAt(0));
return convertView;
}

3、右端首字母跟随数据列表位置高亮显示

这个实现的思路主要用到OnScrollListener这个监听接口,其中onScroll()这个方法会在滚动时调用,那么我们在滚动listView的时候就可以在这里操作首字母的高亮显示了。

@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
ListViewAdapter adapter = (ListViewAdapter)(view.getAdapter());
if(adapter != null){//在首次加载listview时会调用onScroll(),那时候的adapter为null,容错处理
char c1 = adapter.getFristWord(firstVisibleItem + 4);
char c2 = GetPYUntl.getFristWord(c1);
TextView tv = tvMaps.get(c2+"");
if(tv != null){
if(oldTv != null)//如果前次已经有TextView高亮显示,取消高亮效果
oldTv.setTextColor(Color.GRAY);
tv.setTextColor(Color.RED);//设置高亮效果
centerTextView.setText(c1+"");
oldTv = tv;
}
}
}

4、滑动时,出现数据第一个字提示

这个做的不是那么好,如果快速多次滑动还是会出现一些问题。如果大家有兴趣就整改一下哈,还是用到OnScrollListener这个监听接口里 面的onScrollStateChanged方法,逻辑也简单,在滚动时设置显示的TextView可见,在停止滚动时启动定时器2秒后取消 TextView可见。但是对于多次快速滚动来说,这个方法还需要微调一下。

核心代码

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

//构造一个定时器,用于延时2000毫秒取消显示
Runnable runnable = new Runnable() {
@Override
public void run() {
centerTextView.setVisibility(View.INVISIBLE);
}
};
Handler handler = new Handler();

switch (scrollState){
case OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:
//如果手指还接触界面,则取消定时,主要用于第二次后触发事件使用
if(centerTextView.getVisibility() == View.VISIBLE)
handler.removeCallbacks(runnable);
break;
case OnScrollListener.SCROLL_STATE_FLING:
//如果手指离开屏幕,屏幕滑动,设置centerTextView可见
centerTextView.setVisibility(View.VISIBLE);
//如果第二次手指离开屏幕,屏幕滑动,则取消定时,主要用于第二次后触发事件使用
if(centerTextView.getVisibility() == View.VISIBLE)
handler.removeCallbacks(runnable);
break;
case OnScrollListener.SCROLL_STATE_IDLE:
//启动定时任务,于2秒后取消显示
handler.postDelayed(runnable, 1000);
break;
}

}

后记

由于代码量太多,也不好仔细讲实现的逻辑,那么一篇博客肯定写不完,我又比较懒,不喜欢折腾好几个博客来写,所以我在代码里面进行了详尽的注释,希望你参考demo能看懂这些功能的实现思路。

源码请戳(这里

 

作者:enjoy风铃
出处:http://www.cnblogs.com/net168/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则下次不给你转载了。

[转载]如何使php支持短标记?_xiao李阳_新浪博客

mikel阅读(1007)

[转载]如何使php支持短标记?_xiao李阳_新浪博客.

如何使php文件支持短标记?但看这个问题,大部分做php开发的可能都觉得很简单,不就是将php.ini中的short_open_tag = Off改成short_open_tag = On吗?但是,今天我就遇到了问题。

我用的是WAMP的集成环境,刚开始只在php中的php.ini文件中将short_open_tag设为on,但是仍然无法使用短标签。这里我的解决方法:首先输出phpinfo(),查看Loaded Configuration File的目录,看下你载入的配置文件跟你修改的配置文件路径是否一致。改好之后记得重启Apache哦。

后来改了短标记还是不行,于是就将“<?=” 替换成了 “<? echo ”

微信微博年底红包大PK

mikel阅读(899)

QQ截图20150202163347

今天开始得微博抢红包活动顷刻间第一的红包发了10万,还不算那些明星大咖的红包总量,每个微博号5级以上可以领4个,以下得可以领2个,然后就没有然后了,微博上漫天飞舞得都是红包得微博,瞬间抢光也是毫无悬念,更另类的玩法是往红包里放钱!支持明星大咖的粉丝们一次之间打了鸡血般得用支付宝往红包里放得大小不等,粗略算来怎么着也得几百万吧。

 

微博依然打得是明星牌,是个明星不发红包,好像都不好意思和粉丝打招呼似的,于是开始拼粉丝开始,更让人不解的是,抢红包得同时要关注明星的微博,也无疑成为了明星的粉丝,而且往红包里面放钱,谁抢了红包,谁就会自动关注放钱的人的微博,这就是在拿钱卖粉丝的节奏,于是有人在各个明星大咖的红包里放钱,一夜之间赚了2万粉丝,注意这里的粉丝还都是已经绑定了支付宝并通过实名认证的粉丝,可比那些加粉平台的僵尸粉好得多了,突然有种红包被玩儿变味儿的感觉。

微博尽管让人一直质疑广告多,僵尸粉儿横行,商业化太严重的同时,看来人气还是不容忽视,这次发力,上了发红包抢钱的大招儿,再搭载上阿里支付宝这一支付环节,让闭环成为可能,下面就看微信如何出招应对了,去年用红包打了阿里一个措手不及,今年不知道又会有什么大招,很是期待!

[转载]PHP class_exists(),class_exists函数 检查类是否已定义 - PHP100

mikel阅读(981)

[转载]PHP class_exists(),class_exists函数 检查类是否已定义 – PHP100.

class_exists

(PHP 4, PHP 5)

class_exists检查类是否已定义

说明

bool class_exists ( string $class_name [, bool $autoload ] )

如果由 class_name 所指的类已经定义,此函数返回 TRUE,否则返回 FALSE

Example #1 class_exists() 例子

<?php
// Check the class exists before trying to use it
if (class_exists('MyClass')) {
$myclass = new MyClass();
}

?>

class_exists() 默认将会尝试调用 __autoload,如果不想让 class_exists() 调用 __autoload,可以将 autoload 参数设为 FALSE

Example #2 autoload 参数例子

<?php
function __autoload($class)
{
include(
$class '.php');

// Check to see if the include declared the class
if (!class_exists($classfalse)) {
trigger_error("Unable to load class: $class"E_USER_WARNING);
}
}

if (class_exists('MyClass')) {
$myclass = new MyClass();
}

?>

Note:

autoload 参数是 PHP 5 添加的。

参见 interface_exists()get_declared_classes()