unity调用android布局

public void videoTest() {
AdType = 4;
final Activity curActivity = getDiActivity();

(new Handler(curActivity.getMainLooper())).post(new Runnable() {//只要涉及到unity UI,包括更新都需要这一句。否则出错
@SuppressLint(“ResourceType”)
public void run() {
LayoutInflater inflater = LayoutInflater.from(curActivity);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT);
lp.gravity = Gravity.CENTER;
View view = inflater.inflate(R.layout.unityvideo2, null);

videoview = view.findViewById(R.id.videoView);
mmid_layout = view.findViewById(R.id.mid_layout);
mid_ico_img = view.findViewById(R.id.mid_ico_img);
mmid_click_btn = view.findViewById(R.id.mid_click_btn);
mmid_title_txt = view.findViewById(R.id.mid_title_txt);
mmid_title_content_txt = view.findViewById(R.id.mid_title_content_txt);
mlayout_skip = view.findViewById(R.id.layout_skip);
mtv_time = view.findViewById(R.id.tv_time);
mtv_time.setText(“关闭”);

//这里就是将动态布局加入到unity中
totalViewAd = (ViewGroup) curActivity.getWindow().getDecorView();
totalViewAd.addView(view, lp);
}
android完整类:

package com.u3d.com.unityAndroid;

/**
* Created by Admin on 2020/4/9.
*/

public class Unity1Android {
public static Activity activity = null;
ViewGroup totalViewAd;
private static final String[] REQUIRED_PERMISSIONS = new String[]{
“android.permission.READ_EXTERNAL_STORAGE”,
“android.permission.WRITE_EXTERNAL_STORAGE”,
“android.permission.READ_PHONE_STATE”,
“android.permission.INTERNET”,
“android.permission.VIBRATE”
};

//视频部分
LinearLayout mmid_layout, mlayout_skip;
TextView mmid_title_txt, mmid_title_content_txt;
Button mmid_click_btn;
ImageView mid_ico_img;
VideoView videoview;
TextView mtv_time;
Context context;
videoTracerMonitorsBean;

public static Time time;
public long startTime;
Bitmap bmp;
JSONArray jsonObject_video_tracer_monitors;
String JSON;//json

/**
* 调用Unity的方法
*
* @param gameObjectName 调用的GameObject的名称
* @param functionName 方法名
* @param args 参数
* @return 调用是否成功
*/
boolean callUnity(String gameObjectName, String functionName, String args) {
try {
Class<?> classtype = Class.forName(“com.unity3d.player.UnityPlayer”);
Method method = classtype.getMethod(“UnitySendMessage”, String.class, String.class, String.class);
method.invoke(classtype, gameObjectName, functionName, args);
return true;
} catch (ClassNotFoundException e) {

} catch (NoSuchMethodException e) {

} catch (IllegalAccessException e) {

} catch (InvocationTargetException e) {

}
return false;
}

public void videoTest() {
AdType = 4;
final Activity curActivity = getDiActivity();

(new Handler(curActivity.getMainLooper())).post(new Runnable() {
@SuppressLint(“ResourceType”)
public void run() {
LayoutInflater inflater = LayoutInflater.from(curActivity);
LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
lp.gravity = Gravity.CENTER;
View view = inflater.inflate(R.layout.unityvideo2, null);

videoview = view.findViewById(R.id.videoView);
mmid_layout = view.findViewById(R.id.mid_layout);
mid_ico_img = view.findViewById(R.id.mid_ico_img);
mmid_click_btn = view.findViewById(R.id.mid_click_btn);
mmid_title_txt = view.findViewById(R.id.mid_title_txt);
mmid_title_content_txt = view.findViewById(R.id.mid_title_content_txt);
mlayout_skip = view.findViewById(R.id.layout_skip);
mtv_time = view.findViewById(R.id.tv_time);
mtv_time.setText(“关闭”);
// mmid_click_btn.setOnClickListener(this);
// mtv_time.setOnClickListener(this);
// videoview.setVisibility(View.GONE);
// mtv_time.setVisibility(View.GONE);

totalViewAd = (ViewGroup) curActivity.getWindow().getDecorView();
totalViewAd.addView(view, lp);

videoview.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mediaPlayer) {
Log.i(“tag”, “准备完毕”);
mediaPlayer.setOnInfoListener(new MediaPlayer.OnInfoListener() {
@Override
public boolean onInfo(MediaPlayer mp, int what, int extra) {
if (what == MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START) {
// video 视屏播放的时候把背景设置为透明
videoview.setBackgroundColor(Color.TRANSPARENT);
return true;
}
return false;
}
});
}
});

videoview.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
Log.i(“tag”, “播放结束”);
// videocallback.DlgAdvEventEnd(true);
}
});
videoview.setOnErrorListener(new MediaPlayer.OnErrorListener() {
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
Log.i(“tag”, “播放出错”);
return false;
}
});

}
});

}

}
这里是unity部分:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class aarTest : MonoBehaviour
{
// Start is called before the first frame update
AndroidJavaObject m_java;
public Text text;
private void Awake()
{
m_java = new AndroidJavaObject(“com.u3d.com.unityAndroid.Views.Unity1Android”);
}
void Start()
{

}

// Update is called once per frame
void Update()
{

}

public void ArrTest5()
{
m_java = new AndroidJavaObject(“com.u3d.com.unityAndroid.Views.Unity1Android”);
text.text = “开始调用方法”;
m_java.Call(“videoTest”);
text.text += “\n 调用结束”;
}

}
下一篇说说android调用unity及android与unity接口回调通信

 

-END

 

[IOS] —— 音乐播放器进度条的简单实现

利用定时器,UISlider以及它的响应事件简单实现进度条
效果图

%title插图%num
实现的功能有:
1.进度条随着时间的变化自动改变位置
2.拖动进度条时,播放器自动播放到对应的点

代码实现
这个是slider的基本设置

@property (nonatomic, retain) UISlider *slider;
// 进度条
self.slider = [[UISlider alloc] initWithFrame:CGRectMake(0, 0, kScreenWidth – 100, 20)];
self.slider.center = CGPointMake(kControlBarCenterX, kControlBarCenterY + 10);
self.slider.minimumTrackTintColor = [UIColor blueColor];
self.slider.minimumValue = 0.0;
self.slider.maximumValue = 1.0;
//将滑动条加入到控制器上
[self.view addSubview:self.slider];

先介绍拖动滑块时播放器跟着播放到对应的点的方法
//1.监听slider变化状态;(value值变化)(*主要的作用是:监听滑块的拖动)(与滑块自动滑不相关,因为value的值已经在定时器作用下会自动改变值)
//1.1(UIControlEventValueChanged)这个事件的响应比价特殊,其实跟点击按钮效果一样,点击了就会响应,而这里是拖动进度条才会有响应
[self.slider addTarget:self action:@selector(progressAction:) forControlEvents:UIControlEventValueChanged];

progressAction:方法的实现
#pragma mark – 手动拖动进度条的相应地变化
-(void)progressAction:(UISlider *)slider{
//1.slider的value值发生变化时,currentTime也在发生变化(在playerAction中定义了value的公式)
float current = slider.value;
//2.获取*终的currentTime
float nextCurrent = current * CMTimeGetSeconds(self.player.currentItem.duration);
//3.拖动slider导致value的值改变时,player能够让正在进行的item追着时间走
[self.player seekToTime:CMTimeMakeWithSeconds(nextCurrent, 1.0)];
//6.使得计时器一直处于启动状态
self.timer.fireDate =[NSDate distantPast];
}

这样就可以实现拖动滑块时播放器跟着播放到对应的点上

接着介绍一下滑块随着时间自动改变位置的方法
这里应用到的是定时器的方法

@property (nonatomic, retain) NSTimer *timer;
// 计时器 控制播放(slider的跟随时间的滑动)
//使用定时器方法:每间隔一秒响应playerAction方法(因为进度条时间是按每秒变化的)
self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(playerAction) userInfo:nil repeats:YES];
playerAction方法的实现
#pragma mark – 播放计时器方法
-(void)playerAction{
//当前时间 / 总时间 赋值给slider.value.value改变,滑块会跟着滑动,self.player.currentItem.currentTime,self.player.currentItem.duration表示获取当前音频的播放时间和总时间,这时AVPlayer自带的
self.slider.value = CMTimeGetSeconds(self.player.currentItem.currentTime) / CMTimeGetSeconds(self.player.currentItem.duration);
}

通过这样设置,滑块就会跟着时间自动改变到相应的位置

[IOS] —— 声明变量在@interface和@property中的区别

@interface和@implementation部分
@interface RootViewController ()<UITableViewDataSource,UITableViewDelegate,UISearchBarDelegate>
@implementation RootViewControlle

OC中的类必须包括两部分,interface部分和implementation部分,这才是oc中的一个类的完整声明。
OC中将成员变量和成员方法的声明部分放置在interface部分中,包括继承关系,protocal实现关系,都在interface里面的头部进行声明。
然后将实现部分放置在implementation部分中,相当于是将类拆分成声明和实现两部分,这两部分缺一不可,所以在OC中,不妨不要将interface叫做接口,直接叫做类声明部分来得容易理解多了,简而言之,oc中interface是类的一个部分,和implementation共同组成一个完整的类。
在@interface里面声明变量
声明的成员变量是只能在自己类内部使用的,而不能在类的外部使用。

@interface RootViewController ()<UITableViewDataSource,UITableViewDelegate,UISearchBarDelegate>
{
NSString *str;
}

在@property声明变量
(新版的Xcode)这里由@property声明的变量已经自动实现set和get方法,不需要再加上@synthesize
在类的外部可以访问到该变量,在类的内部可以通过下划线+变量名或者self.变量名的方式来访问。

@property (nonatomic, copy) NSMutableArray *dataArray;

[IOS] —— UIScrollerView的基本属性

用UIScrollerView显示大的图片
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@”素材1″]];
//拖动scrollerView内部区域时,滚动的并不是scrollerView,而是里面的图片,也可以理解为是contentsie
self.scrollerView.contentSize = imageView.frame.size;
[self.scrollerView addSubview:imageView];

效果图

%title插图%num
基本属性
//1是否具有弹簧效果
self.scrollerView.bounces = NO;
//2在没有设置contentsiZe的情况下:设置下面两个为YES的作用是:在垂直方向和水平方向上有弹簧效果(类似于页面刷新时的界面能往上拉)
self.scrollerView.alwaysBounceVertical = YES;
self.scrollerView.alwaysBounceHorizontal = YES;

//3.是否显示滚动条(默认为YES)
self.scrollerView.showsVerticalScrollIndicator = NO;
self.scrollerView.showsHorizontalScrollIndicator = NO;

//不要通过索引值去拿到UIScrollerView的子视图
//因为在UIScrollerViewd里面滚动条也是它的子视图
//而且因为滚动条的大小是根据contentsiZe的大小去自适应的,所以在设置contentsiZe前后里面子控件的索引值是不一样的
//你们可以在不同地方打印出它的子控件来发现问题
NSLog(@”%@”,self.scrollerView.subviews);

[IOS] —— 点击当前控制器View响应的方法

代码块
//点击控制器的View自动调用的方法
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
NSLog(@”touchesBegan”);
}
//点击后松开调用的方法
-(void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
NSLog(@”touchesEnded”);
}
//点击后拖动自动调用的方法
-(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
NSLog(@”touchesMoved”);
}
-(void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
NSLog(@”touchesCancelled”);
}

Android:Dialog显示图片

下看一下效果图
%title插图%num %title插图%num

点击TextView弹出Dialog
点击图片Dialog消失

先看一下MainActivity

package com.cxy.demo;

import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.TextView;

import startdialogimageview.qq986945193.dialogdemo.R;

/**
*程序功能:Dialog显示图片
*/
public class MainActivity extends Activity {

Dialog dia;
private TextView tv;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

tv = (TextView) findViewById(R.id.tv);
tv.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
dia.show();
}
});

Context context = MainActivity.this;
dia = new Dialog(context, R.style.edit_AlertDialog_style);
dia.setContentView(R.layout.activity_start_dialog);
ImageView imageView = (ImageView) dia.findViewById(R.id.start_img);
imageView.setBackgroundResource(R.mipmap.iv_android);
//选择true的话点击其他地方可以使dialog消失,为false的话不会消失
dia.setCanceledOnTouchOutside(true); // Sets whether this dialog is
Window w = dia.getWindow();
WindowManager.LayoutParams lp = w.getAttributes();
lp.x = 0;
lp.y = 40;
dia.onWindowAttributesChanged(lp);
imageView.setOnClickListener(
new OnClickListener() {
@Override
public void onClick(View view) {
dia.dismiss();
}
});
}

}

用到的style

<style name=”edit_AlertDialog_style” parent=”@android:style/Theme.Dialog”>
<item name=”android:windowIsFloating”>true</item>
<item name=”android:windowIsTranslucent”>true</item>
<item name=”android:windowNoTitle”>true</item>
<!– 是否启用标题栏 –>
<item name=”android:windowBackground”>@android:color/transparent</item>
<item name=”android:background”>@android:color/transparent</item>
<item name=”android:backgroundDimEnabled”>true</item>
<!– 是否使用背景半透明 –>
</style>

布局文件的话就不上传了,比较简单。

[IOS]——弹窗的实现

弹窗的实现
效果图

%title插图%num
代码实现
self.timer那里只是我自己设置的点击按钮的功能(根据自己需要更改)
//设置弹窗
//UIAlertControllerStyleAlert 在视图中间弹出提示框
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@”开启定时更新新闻功能?” message:nil preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *oneAction = [UIAlertAction actionWithTitle:@”每隔1分钟” style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action){
self.timer = [NSTimer scheduledTimerWithTimeInterval:60.0 target:self selector:@selector(NStimerup) userInfo:nil repeats:YES];
}];
UIAlertAction *fiveAction = [UIAlertAction actionWithTitle:@”每隔5分钟” style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action){
self.timer = [NSTimer scheduledTimerWithTimeInterval:300.0 target:self selector:@selector(NStimerup) userInfo:nil repeats:YES];
}];
UIAlertAction *fifAction = [UIAlertAction actionWithTitle:@”每隔15分钟” style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action){
self.timer = [NSTimer scheduledTimerWithTimeInterval:900.0 target:self selector:@selector(NStimerup) userInfo:nil repeats:YES];
}];
UIAlertAction *canceltimeAction = [UIAlertAction actionWithTitle:@”关闭定时器功能” style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action){
[self.timer invalidate];
self.timer = nil;
}];
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@”取消” style:UIAlertActionStyleCancel handler:nil];
//把提示框按钮添加到提示控制器上
[alertController addAction:oneAction];
[alertController addAction:fiveAction];
[alertController addAction:fifAction];
[alertController addAction:canceltimeAction];
[alertController addAction:cancelAction];
//让提示框可以显示
[self presentViewController:alertController animated:YES completion:nil];

[IOS]——获取新浪微博的.json数据

这里介绍的是获取当前登陆用户以及关注用户的*新微博
微博开放平台的文档介绍https://open.weibo.com/wiki/2/statuses/home_timeline
代码实现
//先取出*前面的微博ID
statusFrame *firststatusF = [self.statusFramesArray firstObject];
//请求的url
NSString *string = nil;
//先判断是否已经存在数据
if(!firststatusF){
//这是获取*新数据
NSMutableString *astring = [[NSMutableString alloc] initWithString:@”这里填url以及所需要的参数(详细看微博的文档介绍)“];
string = astring;
}else{
//这是下拉刷新获取更新的数据(返回比*条微博更新的数据)
NSMutableString *astring = [[NSMutableString alloc] initWithString:@”这里填url以及所需要的参数(注意记得拼接since_id)”];
NSString *since_id = firststatusF.status.idstr;
//拼接出*新的url
[astring appendString:since_id];
string = astring;
}
//创建url
NSURL *accurl = [NSURL URLWithString:string];
//创建请求
NSMutableURLRequest *accrequest = [[NSMutableURLRequest alloc]initWithURL:accurl cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10];
//连接服务器
NSData *received = [NSURLConnection sendSynchronousRequest:accrequest returningResponse:nil error:nil];
NSError *error;
NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:received options:NSJSONReadingMutableContainers error:&error];
//取得微博的字典数组
NSArray *dictArray = dictionary[@”statuses”];

[IOS]——下拉刷新的实现

这里用到的是UIRefreshControl(这是系统自带的下拉刷新,使用非常方便)
效果图

%title插图%num
代码实现
//系统自带的下拉刷新效果
UIRefreshControl *control = [[UIRefreshControl alloc] init];
[control addTarget:self action:@selector(reFreshstatus:) forControlEvents:UIControlEventValueChanged];
//不用自定义frame
[self.tableView addSubview:control];
//一进来就有刷新效果(但刷新数据是要手动的)
[control beginRefreshing];
[self reFreshstatus:control];

 

下面介绍一下那个橙色条的实现(系统自带的下拉刷新只是会有一个刷新图标的显示)
-(void)shownewStatus:(int)count
{
//首先将label控件隐藏在导航栏的后面
UILabel *label = [[UILabel alloc] init];
label.frame = CGRectMake(0, [UIApplication sharedApplication].statusBarFrame.size.height+self.navigationController.navigationBar.frame.size.height-35, [UIScreen mainScreen].bounds.size.width, 35);
label.backgroundColor = [UIColor orangeColor];
if(count == 0){
label.text = @”没有*新的微博数据”;
}else{
//count是传进来的数量
label.text = [NSString stringWithFormat:@”已加载%d条*新的微博数据”,count];
}
label.textColor = [UIColor whiteColor];
//设置文字居中
label.textAlignment = NSTextAlignmentCenter;
label.font = [UIFont systemFontOfSize:16.0];
[self.navigationController.view insertSubview:label belowSubview:self.navigationController.navigationBar];
//动画显示
[UIView animateWithDuration:1.0 animations:^{
label.transform = CGAffineTransformMakeTranslation(0, 35);
} completion:^(BOOL finished) {
[UIView animateWithDuration:1.0 delay:1.0 options:UIViewAnimationOptionCurveLinear animations:^{
//一键回到*初的状态
label.transform = CGAffineTransformIdentity;
} completion:^(BOOL finished) {
//不用的时候把label移除掉
[label removeFromSuperview];
}];
}];
}