拥有一个Class的单​​个实例

时间:2016-09-03 13:54:01

标签: android

概述

我有一个游戏使用ViewPager来显示玩家可以购买的许多地雷。

问题

我创建了一个User课程,以帮助我存储所有用户的信息。

其中一个值是gold,用于购买地雷。 事实是,我不知道在哪里创建用户(怀疑在MainActivity以及如何访问这个新用户的信息来自MineFragment,这是ViewPager

中每个页面的代码

注意:我不想将User对象传递给片段或任何其他类。我希望能够创建单个用户的实例,然后能够从我的代码中的任何位置访问所有这些用户的数据,但在这种情况下,我关心从Fragment(Minefragment)访问它们

用户

public class User {

private String mName;
private int mGold;
private int mExperience;
private int mExperienceLevel;

public User(String name){
    mName = name;
    mGold = 0;
    mExperience = 0;
    mExperienceLevel = 1;
}

// Getters & Setters
[...]

}

MineFragment

public class MineFragment extends Fragment {
// Store instance variables
[...]

private User mUser;

private Button mineUnlockButton;
private View overlay;

[...]

// Store instance variables based on arguments passed
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    [...]

    // HARD CODED VALUES
    mUser = new User("Leonardo");
    mUser.setGold(2000);
}

// Inflate the view for the fragment based on layout XML
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View view = inflater.inflate(mLayout, container, false);

    [...]

    // Unlock Button
    mineUnlockButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            if(mUser.getGold() >= mUnlockCost) {
                overlay.setVisibility(View.GONE); // Remove overlay and button
                mineUnlockButton.setVisibility(View.GONE);
                System.out.println("Gold: " + mUser.getGold() + " | Cost: " + mUnlockCost);
                mUser.setGold(mUser.getGold() - mUnlockCost); // Update user's gold
                System.out.println("Gold: " + mUser.getGold());
                System.out.println("### Mine Purchased ###");

            } else { // Not enough money
                Toast.makeText(getContext(), "Not enough money to purchase", Toast.LENGTH_SHORT).show();
            }
        }
    });

    return view;
}

}

MainFragment

public class MainActivity extends AppCompatActivity {

FragmentPagerAdapter adapterViewPager;
ViewPager viewPager;

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

    viewPager = (ViewPager) findViewById(R.id.vpPager);
    adapterViewPager = new MineAdapter(getSupportFragmentManager());
    viewPager.setAdapter(adapterViewPager);

}

}

这里是GitHub上的project,您可以在其中找到MainActivityUser类,MineFragment以及一些额外的内容(如果您需要)。

3 个答案:

答案 0 :(得分:2)

您需要使用Singleton模式将数据存储在一个单独的位置。

我从您的代码中得到的结果是,您的游戏中有levelslevel,而每个golds需要一些最小数量的 public class LevelModel { private String levelName; private int unlockCost; public String getLevelName() { return levelName; } public int getUnlockCost() { return unlockCost; } public LevelModel(String levelName, int unlockCost) { this.levelName = levelName; this.unlockCost = unlockCost; } } 来解锁它们。

这是200金的测试数据的样子: -

enter image description here enter image description here

模型类

让我们从Level类开始-lavel具有名称和最小金threashold

public class User {
    private String userName;
    private int gold;
    private int experience;
    private int experienceLevel = 1;

    /**
     * @param userName
     * @param gold
     * @param experience
     * @param experienceLevel
     */
    public User(String userName, int gold, int experience, int experienceLevel) {
        this.userName = userName;
        this.gold = gold;
        this.experience = experience;
        this.experienceLevel = experienceLevel;
    }

    //Setters

    public void setGold(int gold) {
        this.gold = gold;
    }

    public void setExperience(int experience) {
        this.experience = experience;
    }

    public void setExperienceLevel(int experienceLevel) {
        this.experienceLevel = experienceLevel;
    }

    //Getters

    public String getUserName() {
        return userName;
    }

    public int getGold() {
        return gold;
    }

    public int getExperience() {
        return experience;
    }

    public int getExperienceLevel() {
        return experienceLevel;
    }
}

接下来将是User类,所有字段都是自解释的

public class CenterRepository {

    public void setCurrentUser(User currentUser) {
        this.currentUser = currentUser;
    }

    private User currentUser;
    ArrayList<LevelModel> listOfLavels = new ArrayList<>();
    private static CenterRepository singletonInstance;

    private CenterRepository() {
    }

    public static CenterRepository getSingletonInstance() {
        if (null == singletonInstance) {
            singletonInstance = new CenterRepository();
        }
        return singletonInstance;
    }

    public User getCurrentUser() {
        return currentUser;
    }


    public ArrayList<LevelModel> getListOfLavels() {
        return listOfLavels;
    }
}

现在您需要一个地方来存储,更新和访问您的游戏数据,此类将作为Singleton类来保存您的所有游戏数据。

ViewPager

现在,对于第二部分,如何从package com.fet.minebeta.ui; import android.content.Context; import android.support.v4.view.PagerAdapter; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.FrameLayout; import android.widget.TextView; import android.widget.Toast; import com.fet.minebeta.R; import com.fet.minebeta.data.CenterRepository; /** * Created by FET on 08/09/2016. * All rights reserved. * Please contact @fettucciari.leonardo@gmail.com */ public class MineAdapter extends PagerAdapter { private Context mContext; private LayoutInflater mLayoutInflater; public MineAdapter(Context context) { mContext = context; mLayoutInflater = (LayoutInflater) mContext .getSystemService(Context.LAYOUT_INFLATER_SERVICE); } @Override public int getCount() { //Fill Data directly from Repository return CenterRepository.getSingletonInstance().getListOfLavels().size(); } @Override public boolean isViewFromObject(View view, Object object) { return view == ((FrameLayout) object); } @Override public Object instantiateItem(ViewGroup container, final int position) { final View itemView = mLayoutInflater.inflate(R.layout.carousal_page, container, false); switch (position) { case 0: itemView.setBackgroundResource(R.color.iron); break; case 1: itemView.setBackgroundResource(R.color.coal); break; case 2: itemView.setBackgroundResource(R.color.gold); break; } //Mine Name ((TextView) itemView.findViewById(R.id.mineName)).setText( CenterRepository.getSingletonInstance().getListOfLavels().get(position).getmName()); //Mine Cost ((TextView) itemView.findViewById(R.id.mineCost)).setText("" + CenterRepository.getSingletonInstance().getListOfLavels().get(position).getUnlockCost()); //Mine Cost ((TextView) itemView.findViewById(R.id.mineDropRate)).setText("" + CenterRepository.getSingletonInstance().getListOfLavels().get(position).getDropRate()); //Mineral Name ((TextView) itemView.findViewById(R.id.mineMineral)).setText( CenterRepository.getSingletonInstance().getListOfLavels().get(position).getMineral().getName()); //Mineral Drop Rate ((TextView) itemView.findViewById(R.id.mineDropRate)).setText("" + CenterRepository.getSingletonInstance().getListOfLavels().get(position).getMineral().getValue()); // Unlock Button itemView.findViewById(R.id.unlockButton).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (CenterRepository.getSingletonInstance().getCurrentUser().getGold() >= CenterRepository.getSingletonInstance().getListOfLavels().get(position).getUnlockCost()) { //If User has more gold than cost to unlock hide lock image and buy it CenterRepository.getSingletonInstance().getCurrentUser().setGold( CenterRepository.getSingletonInstance().getCurrentUser().getGold() - CenterRepository.getSingletonInstance().getListOfLavels().get(position).getUnlockCost()); // Update user's gold Toast.makeText(mContext, "Reduced " + CenterRepository.getSingletonInstance().getListOfLavels().get(position).getUnlockCost() + "\n Updated Gold " + CenterRepository.getSingletonInstance() .getCurrentUser().getGold(), Toast.LENGTH_LONG).show(); } else { // Not enough money Toast.makeText(mContext, "Not enough money to purchase You need " + (CenterRepository.getSingletonInstance().getListOfLavels().get(position).getUnlockCost() - CenterRepository.getSingletonInstance().getCurrentUser().getGold()) + "More", Toast.LENGTH_SHORT).show(); } } }); container.addView(itemView); return itemView; } @Override public void destroyItem(ViewGroup container, int position, Object object) { container.removeView((FrameLayout) object); } } 访问和更新数据。我已经增强了您的视图寻呼机以使用视图而不是片段

  

MineAdapter已更新**

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
        android:id="@+id/mineName"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="@dimen/activity_horizontal_margin"
        android:layout_weight="1"
        android:gravity="center_vertical"
        android:text="COAL MINE"
        android:textColor="@android:color/white"
        android:textSize="25sp" />


    <TextView
        android:id="@+id/mineCost"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="5"
        android:gravity="center"
        android:text="1000"
        android:textColor="@android:color/white"
        android:textSize="50sp" />

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="3"
        android:paddingEnd="100dp"
        android:paddingStart="100dp">

        <TextView
            android:id="@+id/mineMineral"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentStart="true"
            android:layout_alignTop="@+id/mineDropRate"
            android:text="COAL"
            android:textAlignment="center"
            android:textColor="@android:color/white"
            android:textSize="25sp" />

        <TextView
            android:id="@+id/mineDropRate"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentEnd="true"
            android:layout_centerVertical="true"
            android:text="1"
            android:textAlignment="center"
            android:textColor="@android:color/white"
            android:textSize="25sp" />

    </RelativeLayout>
</LinearLayout>

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/unlockButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:text="Unlock" />

</RelativeLayout>

有一点需要注意,carousal页面将FrameLayout作为rootlayout。如果您打算使用任何其他更新addview并相应删除视图功能

  

carousal_page.xml **更新了你不需要为每种矿物分开布局

public class MainActivity extends AppCompatActivity {

    PagerAdapter adapterViewPager;
    ViewPager viewPager;

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

        //  Add Test User from Activity
        CenterRepository.getSingletonInstance().setCurrentUser(new User("FET", 200, 20, 10));

        //Add Test Mines
        CenterRepository.getSingletonInstance().getListOfLavels().add(new Mine("Iron", new Mineral("Iron Mineral", 1), 100, 2));
        CenterRepository.getSingletonInstance().getListOfLavels().add(new Mine("Coal", new Mineral("Coal Mineral", 3), 200, 2));
        CenterRepository.getSingletonInstance().getListOfLavels().add(new Mine("Gold", new Mineral("Gold Mineral", 2), 300, 2));

        viewPager = (ViewPager) findViewById(R.id.vpPager);
        viewPager.setAdapter(new MineAdapter(this));

        Toast.makeText(getApplicationContext(), "Current Credits " + CenterRepository.getSingletonInstance()
                .getCurrentUser().getGold(), Toast.LENGTH_LONG).show();


    }


}

模型类是如此松散耦合,你可以将它移动到任何地方,它可以正常工作。

  

活动类,测试数据已更新**

pyvenv env
source env/bin/activate
pip install sqlalchemy

答案 1 :(得分:1)

这不是一个糟糕的开始......

因为那可能是你唯一的游戏初始化类,你需要让它成为单身。 java中的一个技巧是,如果将类更改为枚举并创建一个名为INSTANCE的字段

在onCreate调用中的MainActivity中使用

User.INSTANCE

这将使用User类中的默认值初始化游戏。您可以访问User类和字段的所有方法。

答案 2 :(得分:0)

在您的用户类中创建一个静态用户,代表正在玩游戏的人:

    public class User {

    public static User user = new User("Name Here");

    private String mName;
    private int mGold;
    private int mExperience;
    private int mExperienceLevel;

    public User(String name){
        mName = name;
        mGold = 0;
        mExperience = 0;
        mExperienceLevel = 1;
    }
    // Getters & Setters
    [...]

使用例如:

访问它
    User.user.setGold(User.user.getGold() + 1);