Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/heroku/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android:确定代码应该驻留在活动视图还是自定义视图中_Android - Fatal编程技术网

Android:确定代码应该驻留在活动视图还是自定义视图中

Android:确定代码应该驻留在活动视图还是自定义视图中,android,Android,随着我对活动和自定义视图的熟悉,我一直在决定与视图及其父活动相关的代码应该放在哪里。需要两者都访问的附加自定义对象,关于如何构造代码的选项是无穷无尽的。以下是我的问题的细节: 相关类/文件: GameActivity扩展活动:它使用的布局包含一些自定义视图 MapView扩展视图:这包含在GameActivity使用的布局中 世界:定义自定义世界对象的自定义类 预期结果: GameActivity调出包含MapView的布局。MapView的onDraw()函数使用来自世界对象的信息在画布上绘制

随着我对活动和自定义视图的熟悉,我一直在决定与视图及其父活动相关的代码应该放在哪里。需要两者都访问的附加自定义对象,关于如何构造代码的选项是无穷无尽的。以下是我的问题的细节:

相关类/文件:
GameActivity扩展活动:它使用的布局包含一些自定义视图

MapView扩展视图:这包含在GameActivity使用的布局中

世界:定义自定义世界对象的自定义类

预期结果:
GameActivity调出包含MapView的布局。MapView的onDraw()函数使用来自世界对象的信息在画布上绘制地图

问题:
MapView所需的世界对象是从以前保存的文件加载的。我可以通过多种不同的方式将该对象放到地图视图中,这就是我犹豫不决的地方。我已经经历了以下迭代。(注意,它们都是有效的。我要寻找的是一种方法优于另一种方法的理由。)

版本1:
游戏活动:它所做的只是设置内容布局(layout_.xml中带有映射视图的布局)

MapView:具有从文件加载世界对象的所有代码,并使用它引用所需的图形参数

World:一个简单的自定义类,其构造函数中有3个参数

然后,我决定从文件加载World对象应该是World类本身的一个方法,而不是MapView的onCreate()方法。由于加载世界文件是在没有世界对象的情况下永远不会做的事情,所以它应该是类方法。因此,我在世界类中创建了一个loadWorld(stringworld\u name)方法。现在文件看起来像这样:

版本2:
游戏活动:它所做的只是设置内容布局(layout_.xml中带有映射视图的布局)

MapView:使用构造函数创建一个新的世界对象,然后调用它的loadWorld()方法以使用文件信息更新它

World:一个简单的自定义类,在其构造函数中包含3个参数,以及一个loadWorld()方法

最后,我决定MapView中只应包含绘图活动。拥有一个世界物体的全部意义就是能够传递它,对吗?因此,我将World construction/loading从视图中移到活动中。这导致必须在MapView中创建setter方法,以便能够从创建World对象的父活动传递该对象

版本3:
GameActivity:设置布局,创建一个世界对象,并调用它的loadWorld()方法从文件中加载它。按Id引用MapView,然后调用MapView的setWorld()方法,以通过传递World对象的实例

地图视图:从外部设置世界对象。使用此对象的信息绘制地图

World:一个简单的自定义类,在其构造函数中包含3个参数,以及一个loadWorld()方法。

好的,这就是我目前的处境。我的问题是,尽管我喜欢我所选择的约定,即视图只包含与绘图相关的代码,并将与类相关的方法保留在它们自己的类中——似乎当我切换到该方法时,我突然更频繁地创建临时对象,并将对象从一个活动传递到另一个活动,再到视图等等。这看起来开销要大得多,但同时这也是整个抽象点,对吗?抽象出一个类,这样您就可以从中实例化一个对象并传递它。然而,在我看来,抽象出的东西越多,处理对象就变得越复杂

我想我想问的是,我不从MapView本身的文件中加载世界,是否会让事情变得更复杂?我只是固执地不想让代码涉及到从视图类中的文件读取对象吗?把它放在自己的课堂上或活动中会更好吗?在做出这些决定时,我需要考虑什么?有没有一个我甚至都不知道的解决我进退两难的办法

我认为答案将是个人偏好,但我想知道是否存在以这种或那种方式做这件事的惯例,或者是否有确凿的理由来构建某种方式。我一直在试图寻找这个问题的答案,但我认为我使用了错误的搜索词。我经常遇到一些描述如何构造活动/视图结构的东西,但对其中的代码一无所知。当有代码时,不可避免地会有人教你如何在活动之间传递数据,或者在活动和视图之间传递数据,等等。我知道所有这些方法。我只是不知道该用哪一个

我一直在看的一些链接:



编辑:包含有关应用程序结构和代码示例的更多详细信息

游戏活动:

/*IMPORT STATEMENTS REMOVED*/

public class GameActivity extends Activity implements OnTouchListener {

@Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.game);  
    Log.d("LOGCAT", "GameActivity Started");

    //get the world_name from MenuActivity
    Intent intent = getIntent();
    String world_name = intent.getStringExtra(MenuActivity.EXTRA_MESSAGE);

    //load the world
    World world = loadWorld(world_name);

    //create a tilemap and get the tile translator array from it 
            //need to convert this to a static Map
    TileMap tileMap = new TileMap(this);    
    Map<Integer,Bitmap> tileTranslator = tileMap.getTileTranslator();

    //Create a reference to the MapView object and set the translator
    MapView mapView = (MapView) findViewById(R.id.map_view);
    mapView.setArgs(world, tileTranslator);

    //implement the OnTouchSwipeListener
    mapView.setOnTouchListener(new OnSwipeTouchListener() {

            /*CODE REMOVED*/
    });

}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
    case android.R.id.home:
        NavUtils.navigateUpFromSameTask(this);
        return true;
    }
    return super.onOptionsItemSelected(item);
}

public World loadWorld(String world_name) {

//Create a dummy world to load into - why?!
    World dummy_world = new World();

    //load the world 
    Log.d("LOGCAT", "Loading the World");
    try {
        World world = dummy_world.loadWorld(this, world_name);
        return world;
    } catch (IOException e) {
    //do nothing!
    } catch (ClassNotFoundException f) {
    //do nothing!
    }

    return dummy_world; //if world load fails, send back the default world
                        // NOTE: it's not saved!!!

}

}
/*已删除导入语句*/
公共类GameActivity扩展了活动实现OnTouchListener{
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.game);
Log.d(“LOGCAT”,“游戏活动开始”);
//从MenuActivity获取世界名称
Intent=getIntent();
String world_name=intent.getStringExtra(MenuActivity.EXTRA_消息);
//载入世界
世界世界=负荷世界(世界名称);
//创建一个tilemap并从中获取tile转换器数组
//需要将其转换为静态映射
TileMap TileMap=新TileMap(此);
Map TiletTranslator=tileMap.getTileTranslator();
//创建对MapView对象的引用并设置转换器
MapView MapView=(MapView)findViewB
/*IMPORT STATEMENTS REMOVED*/

public class MapView extends View implements OnClickListener {

protected Context context;
public World world;
public Map<Integer,Bitmap> tileTranslator;

    //hardcoded variables for testing
private int tile_width = 50;
private int tile_height = 50;
public int screen_width = 12;
public int screen_height = 6;
public int playerX = 4;
public int playerY = 7;


public MapView(Context context, AttributeSet attrs) {

    super(context, attrs);
    this.context = context;
    Log.d("LOGCAT", "MapView created"); 

    setOnClickListener(this);

}

@Override
public void onDraw(Canvas canvas) {

        /*CODE REMOVED*/
    }

//ugly method, need to break it out into individual setters
public void setArgs(World world, Map<Integer,Bitmap> tileTranslator){

    this.world = world;
    this.tileTranslator = tileTranslator;

}

}
/*IMPORT STATEMENTS REMOVED*/

public class World implements Serializable {

public String world_name;
public int world_width;
public int world_height;
public int[][] world_map;

public World() { //default world - I don't even want this constructor here!

    world_name = "default_world";
    world_width = 1;
    world_height = 1;

    world_map = createWorld(world_width, world_height);

}

public World(String world_name, int world_width, int world_height) {

    //set the world attributes
    this.world_name = world_name;
    this.world_width = world_width;
    this.world_height = world_height;

    //generate the map
    world_map = createWorld(world_width, world_height);

}

private int[][] createWorld(int world_width, int world_height) {

    //create a local tile map 
    int[][] world_map = new int[world_width][world_height];

    //get a randomizer to fill the array with - {temporary solution}
    Random rand = new Random();

    //fill the tile map array with random numbers between 0 and 2
    for(int row = 0; row < world_map.length; row++) {
        for (int col = 0; col < world_map[row].length; col++) {
            world_map[row][col] = rand.nextInt(3);  //static number, needs variable!
                                                    //3 is the number of tile types
        }
    }

    return world_map;

}   

public void saveWorld(Context context, String world_name, World world) throws IOException {

    FileOutputStream fos = context.openFileOutput(world_name, Context.MODE_PRIVATE);
    ObjectOutputStream oos = new ObjectOutputStream(fos);
    oos.writeObject(world);
    oos.close();

}

public World loadWorld(Context context, String world_name) throws IOException, ClassNotFoundException {

    FileInputStream fis = context.openFileInput(world_name);
    ObjectInputStream ois = new ObjectInputStream(fis);
    World world = (World)ois.readObject();

    /*this.world_name = world.world_name;
    this.world_width = world.world_width;
    this.world_height = world.world_height;
    this.world_map = world.world_map;*/  //why doesn't this work?
    return world;

}

}
public class World {
    private Rect mWorldAABB;
    private static World sInstance = null;
    private World() {
    // Put your code to read whatever you want from file
    };

    private static World getInstance() {
        if (sInstance == null) {
             sInstance = new World();
        }
         return sInstance;
    }

    private Rect getWorldRect() {
        return mWorldAABB;
    }
    public static Rect getWorldDimensions() {
        return getInstance().getWorldRect();
}
public class WorldBuilder {

    private File worldFile;
    private String name = "default_world";
    private int width = 1;
    private int height = 1;

    public static WorldBuilder fromFile(File worldFile){
        WorldBuilder worldBuilder = new WorldBuilder();
        worldBuilder.worldFile = worldFile;
        return worldBuilder;
    }

    public WorldBuilder withName(String name){
        this.name= name;
        return this;
    }

    public WorldBuilder withWidth(int width){
        this.parameter2 = param2;
        return this;
    }

    public WorldBuilder withHeight(int height){
        this.height = height;
        return this;
    }

    public World build(){
        World world = new World(name,width,height);
        if(worldFile!=null)
            world.loadWorld(worldFile);
        return world;
    }    
}
World world = WorldBuilder.fromFile(worldFile)
        .withName(p1)
        .withWidth(p2)
        .withHeight(p3)
        .build();
World world = WorldBuilder.fromFile(null).build();