您的位置:首页 > 其它

仿QQ电话/消息切换的自定义布局结合Fragment解决你的需求!

2015-08-05 15:25 549 查看
转载请注明出处:王亟亟的大牛之路

先上模仿的对象:QQ的电话/消息 界面



用户点击消息或者电话会切换不同的界面

然后再上自己实现的界面



然后再附带了一些每一个Fragment内部的操作,来模拟切换后的效果

实现方法: 一个自定义控件+下面的Fragment.利用setOnSegmentControlViewClickListener方法来监听用户的点击来对界面进行操作。

项目目录结构



一个主Activity加一系列分页的Fragment(其实这里可以用Java代码来添加Fragment,但是考虑到大家的使用性,还是用麻烦的方法。毕竟 Copy走就直接可以改每一个单独的Fragment进行修改了)

主Activity

package com.wjj.wjjdemo;
import com.wjj.wjjdemo.customView.SegmentControlView;
import com.wjj.wjjdemo.customView.SegmentControlView.onSegmentControlViewClickListener;
import com.wjj.wjjdemo.fragment.fragmenta;
import com.wjj.wjjdemo.fragment.fragmentb;
import com.wjj.wjjdemo.fragment.fragmentc;

import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;

public class MainActivity extends Activity {
private SegmentControlView SegmentControlView = null;
/*等会要用于切换的3个Fragment*/
private fragmenta fragmenta;
private fragmentb fragmentb;
private fragmentc fragmentc;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FindById();
// 设置默认的Fragment
setDefaultFragment();
Listener();
}

private void FindById(){
SegmentControlView = (SegmentControlView) findViewById(R.id.SegmentControlView);
}

private void Listener(){
SegmentControlView.setOnSegmentControlViewClickListener(new onSegmentControlViewClickListener() {

@Override
public void onSegmentControlViewClick(View view, int position) {
FragmentManager fm = getFragmentManager();
// 开启Fragment事务
FragmentTransaction transaction = fm.beginTransaction();

switch (position) {
case 0:
if (fragmenta == null)
{
fragmenta = new fragmenta();
}
// 使用当前Fragment的布局替代id_content的控件
transaction.replace(R.id.fragmentlayout, fragmenta);
// 事务提交
transaction.commit();
break;
case 1:
if (fragmentb == null)
{
fragmentb = new fragmentb();
}
// 使用当前Fragment的布局替代id_content的控件
transaction.replace(R.id.fragmentlayout, fragmentb);
// 事务提交
transaction.commit();
break;
case 2:
if (fragmentc == null)
{
fragmentc = new fragmentc();
}
// 使用当前Fragment的布局替代id_content的控件
transaction.replace(R.id.fragmentlayout, fragmentc);
// 事务提交
transaction.commit();
break;
default:
break;
}
}
});
}

private void setDefaultFragment(){
FragmentManager fm = getFragmentManager();
FragmentTransaction transaction = fm.beginTransaction();
fragmenta=new fragmenta();
transaction.replace(R.id.fragmentlayout, fragmenta);
transaction.commit();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}


其实 当中监听时间的transaction.commit(); 些多余了,大家就自行修改吧,放到函数外面就行了,因为会break出去,并不需要每一个case里都要加

自定义View

@SuppressLint("NewApi")
public class SegmentControlView extends LinearLayout {

private TextView textView1 = null;
private TextView textView2 = null;
private TextView textView3 = null;
private View verTextView1 = null;//中间的竖线
private View verTextView2 = null;//中间的竖线
private onSegmentControlViewClickListener listener;

public SegmentControlView(Context context) {
super(context);
initView();
}

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

public SegmentControlView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView();
}

private void initView() {

textView1 = new TextView(getContext());
textView2 = new TextView(getContext());
textView3 = new TextView(getContext());
verTextView1 = new View(getContext());
verTextView2 = new View(getContext());

textView1.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 1));
verTextView1.setLayoutParams(new LayoutParams(1, LayoutParams.MATCH_PARENT));
textView2.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 1));
verTextView2.setLayoutParams(new LayoutParams(1, LayoutParams.MATCH_PARENT));
textView3.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, 1));

setSegmentText(0, getContext().getString(R.string.noti_msg));
setSegmentText(1, getContext().getString(R.string.friends_list));
setSegmentText(2, getContext().getString(R.string.all_list));
setSegmentTextSize(16);//设置文字大小

XmlPullParser xrp = getResources().getXml(R.drawable.seg_text_color_selector);
try {
ColorStateList csl = ColorStateList.createFromXml(getResources(), xrp);
textView1.setTextColor(csl);
textView2.setTextColor(csl);
textView3.setTextColor(csl);
} catch (Exception e) {
}
textView1.setGravity(Gravity.CENTER);
textView2.setGravity(Gravity.CENTER);
textView3.setGravity(Gravity.CENTER);
textView1.setPadding(3, 6, 3, 6);
textView2.setPadding(3, 6, 3, 6);
textView3.setPadding(3, 6, 3, 6);
textView1.setBackgroundResource(R.drawable.seg_left);
textView2.setBackgroundResource(R.drawable.seg_middle);
textView3.setBackgroundResource(R.drawable.seg_right);
verTextView1.setBackgroundColor(getResources().getColor(R.color.blue));
verTextView2.setBackgroundColor(getResources().getColor(R.color.blue));

this.removeAllViews();
this.addView(textView1);
this.addView(verTextView1);
this.addView(textView2);
this.addView(verTextView2);
this.addView(textView3);
this.invalidate();

textView1.setSelected(true);

textView1.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
if (textView1.isSelected()) {
return;
}
textView1.setSelected(true);
textView2.setSelected(false);
textView3.setSelected(false);
if (listener != null) {
listener.onSegmentControlViewClick(textView1, 0);
}
}
});
textView2.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
if (textView2.isSelected()) {
return;
}
textView2.setSelected(true);
textView1.setSelected(false);
textView3.setSelected(false);
if (listener != null) {
listener.onSegmentControlViewClick(textView2, 1);
}
}
});

textView3.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
if (textView3.isSelected()) {
return;
}
textView3.setSelected(true);
textView1.setSelected(false);
textView2.setSelected(false);
if (listener != null) {
listener.onSegmentControlViewClick(textView2, 2);
}
}
});
}

/**
* 设置字体大小 单位dip
* @param dp
*/
public void setSegmentTextSize(int dp) {
textView1.setTextSize(TypedValue.COMPLEX_UNIT_DIP, dp);
textView2.setTextSize(TypedValue.COMPLEX_UNIT_DIP, dp);
textView3.setTextSize(TypedValue.COMPLEX_UNIT_DIP, dp);
}

/**
* 设置文字
* @param text
* @param position
*/
public void setSegmentText(int position, CharSequence text) {
if (position == 0) {//左
textView1.setText(text);
}
if (position == 1) {//中
textView2.setText(text);
}
if (position == 2) {//右
textView3.setText(text);
}
}

public void setOnSegmentControlViewClickListener(onSegmentControlViewClickListener listener) {
this.listener = listener;
}

public static interface onSegmentControlViewClickListener{

/**
* @param v
* @param position 0-左边 1-中间 2-右边
*/
public void onSegmentControlViewClick(View v,int position);
}

/**
* dp与px转化函数
* @param context
* @param dp
* @return
*/
private static int dp2Px(Context context, float dp) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dp * scale + 0.5f);
}
}


整体封装的还不错,需要修改UI的观众老爷可自行进行修改,大体功能已经实现了

3个Fragment中的一个

public class fragmenta extends Fragment{
Button fragmentaButton;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
View view= inflater.inflate(R.layout.fragemnta, container, false);
fragmentaButton=(Button)view.findViewById(R.id.fragmentaButtona);
fragmentaButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Toast.makeText(getActivity(), "fragmenta", 1).show();
}
});
return view;
}

}


主布局文件

<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"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.wjj.wjjdemo.MainActivity"
android:background="@color/white">

<com.wjj.wjjdemo.customView.SegmentControlView
android:id="@+id/SegmentControlView"
android:layout_width="240dp"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:background="@drawable/seg_linear"
android:padding="0.5dp" >
</com.wjj.wjjdemo.customView.SegmentControlView>

<FrameLayout
android:id="@+id/fragmentlayout"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_alignParentBottom="true"
android:layout_below="@+id/SegmentControlView" >
</FrameLayout>

</RelativeLayout>


这里要补充下,楼主在FrameLayout节点这一部分犯了一个错误,之前用Fragment来填充这一部分,导致出现了2个View重叠的问题,所以用FrameLayout之类的布局来填充就好了。

大体主要的代码就这些了,源码在下面会补上,布局文件资源文件什么的都在里面了,大家拿来就可以用。

http://yunpan.cn/cdcyxcXkLZnye 访问密码 0d8e

有疑问欢迎QQ联系452270579
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: