更改Android

时间:2017-03-31 03:52:29

标签: java android listview

我无法改变数组适配器中的textView字体。我通常使用下面的代码更改字体

TextView textview = (TextView) findViewById(R.id.textViewsawtyat1);
Typeface face2 = Typeface.createFromAsset(textview.getContext().getAssets(), "fonts/Israr.ttf");
textview.setTypeface(face2);

但是当我尝试使用该方法时出现错误,因为它在创建数组适配器之前尝试运行此代码。这是整个班级的代码。

public class PlayerMainScreen extends Activity implements View.OnTouchListener, AdapterView.OnItemClickListener{
    private ListView listView;
    private String TAG = "Album Main Screen";
    private FirebaseDatabase firebaseDatabaseInstance;
    private DatabaseReference booksInstance;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_player_main_screen);
        init();
        getData();
    }

    private void init(){

        listView = (ListView) findViewById(R.id.listView);


        listView.setOnItemClickListener(this);

    }
    private void getData(){

        Constants.showLoadingDialog(this);
        firebaseDatabaseInstance = FirebaseDatabase.getInstance();

        // get reference to 'users' node
        booksInstance = firebaseDatabaseInstance.getReference("sawtyat");

        booksInstance.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                setData(dataSnapshot);
            }

            @Override
            public void onCancelled(DatabaseError error) {
                // Failed to read value
                Log.w(TAG, "Failed to read value.", error.toException());
            }
        });
    }

    List<List<String>> playerList;
    List<String> temp1, temp2;
    private void setData(DataSnapshot dataSnapshot){
        playerList = new ArrayList<>();
        temp1 = new ArrayList<>();
        temp2 = new ArrayList<>();

        for (DataSnapshot alert: dataSnapshot.getChildren()) {
            Log.d("cover_image_name", (String) alert.child("book_name").getValue());
            Log.d("cover_image_path", (String) alert.child("sound_path").getValue());

            temp1.add((String) alert.child("book_name").getValue());
            temp2.add((String) alert.child("sound_path").getValue());
        }
        playerList.add(temp1);
        playerList.add(temp2);
        if(playerList.size() > 0){
            setListView();
        }else{
            Toast.makeText(this, "No data Found.", Toast.LENGTH_SHORT).show();
        }
    }

    private void setListView(){
        ArrayAdapter arrayAdapter = new ArrayAdapter(this, R.layout.fragment_player_main_screen, R.id.textViewsawtyat1, playerList.get(0));


        listView.setAdapter(arrayAdapter);

TextView textview = (TextView) findViewById(R.id.textViewsawtyat1);
        Typeface face3 = Typeface.createFromAsset(textview.getContext().getAssets(), "fonts/Isra.ttf");
        textview.setTypeface(face3);

        Constants.hideDialog();
    }

    @Override
    public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {

        PlayAudio(position);
    }

    private void PlayAudio(int position){

        try {

            Intent intent = new Intent(Intent.ACTION_VIEW);
            Uri data = Uri.parse(playerList.get(1).get(position));
            intent.setDataAndType(data, "audio/*");
            startActivity(intent);
        }catch (Exception e){
            e.printStackTrace();
            Toast.makeText(this, "No player Found.", Toast.LENGTH_SHORT).show();
        }
    }
}

我要更改的文本视图字体位于方法setListView

这是我得到的错误

                 --------- beginning of crash
E/AndroidRuntime: FATAL EXCEPTION: main
                  Process: com.metwally.almostshar.almostshar, PID: 3116
                  java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.widget.TextView.getContext()' on a null object reference
                      at com.metwally.almostshar.almostshar.activities.PlayerMainScreen.setListView(PlayerMainScreen.java:190)
                      at com.metwally.almostshar.almostshar.activities.PlayerMainScreen.setData(PlayerMainScreen.java:179)
                      at com.metwally.almostshar.almostshar.activities.PlayerMainScreen.access$000(PlayerMainScreen.java:40)
                      at com.metwally.almostshar.almostshar.activities.PlayerMainScreen$5.onDataChange(PlayerMainScreen.java:151)
                      at com.google.android.gms.internal.zzbpx.zza(Unknown Source)
                      at com.google.android.gms.internal.zzbqx.zzZS(Unknown Source)
                      at com.google.android.gms.internal.zzbra$1.run(Unknown Source)
                      at android.os.Handler.handleCallback(Handler.java:739)
                      at android.os.Handler.dispatchMessage(Handler.java:95)
                      at android.os.Looper.loop(Looper.java:148)
                      at android.app.ActivityThread.main(ActivityThread.java:5417)
                      at java.lang.reflect.Method.invoke(Native Method)
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

4 个答案:

答案 0 :(得分:2)

如果您使用单个字体在整个适配器中应用,请更喜欢使用自定义视图。以下是您如何做到这一点的例子。

自定义视图class

public class CustomTextView extends TextView {

    public CustomTextView (Context context) {
        super(context);
        init();
    }

    public CustomTextView (Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public CustomTextView (Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }


    private void init() {
        setTypeface(Typeface.createFromAsset(getContext().getAssets(), YOUR_FONT));
    }

}

然后在您的layout.xml中使用它,如下所示

<your.package.name.CustomTextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:textSize="25sp"
    android:background="@color/colorPrimary"
    android:textColor="@android:color/white"/>

答案 1 :(得分:1)

您可以通过创建扩展Textview的类并将代码编写为在其中应用新字体并在列表视图中使用该textivew来将自定义字体设置为textview。

我在资源文件夹中保留了三种字体并使用它们,如下面的代码所示。

public class CustomTextView extends TextView {
    public final String ANDROID_SCHEMA = "http://schemas.android.com/apk/res/android";

    public CustomTextView(Context context) {
        super(context);
        setTextViewFont(context, 0);

    }

    public CustomTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        try {
            int textStyle = attrs.getAttributeIntValue(ANDROID_SCHEMA, "textStyle", Typeface.NORMAL);
            setTextViewFont(context, textStyle);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public CustomTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        try {
            int textStyle = attrs.getAttributeIntValue(ANDROID_SCHEMA, "textStyle", Typeface.NORMAL);
            setTextViewFont(context, textStyle);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * Set textstyle
     *
     * @param context   pass context
     * @param fontStyle pass the desired font style <br/>
     *                  0: normal <br/>
     *                  1: bold <br/>
     *                  2: italic <br/>
     */
    public void setTextViewFont(Context context, int fontStyle) {
        if (!isInEditMode()) {
            switch (fontStyle) {
                case Typeface.NORMAL:
                    setTypeface(FontFaceCache.getTypeface("fonts/Roboto-Regular.ttf", context));
                    break;
                case Typeface.BOLD:
                    setTypeface(FontFaceCache.getTypeface("fonts/Roboto-Bold.ttf", context));
                    break;
                case Typeface.ITALIC:
                    setTypeface(FontFaceCache.getTypeface("fonts/Roboto-Italic.ttf", context));
                    break;
            }
        }
    }

然后在我的布局中,我使用此textview如下:

<com.abc.CustomTextView
  blah blah...

而不是普通的android textview

在我的回答中,我使用了FontFaceCache类,因为每次从资产文件夹访问字体文件都是性能消耗,如果列表视图或视图中有很多Textview,则会出现UI jagginess / jerks / UI中的rssult。
为了解决这个问题,我使用了如下的hashmap,并且每次都从那个

获取字体
public class FontFaceCache {
    private static HashMap<String, Typeface> fontCache = new HashMap<>(3);

    public static Typeface getTypeface(String fontname, Context context) {
        Typeface typeface = fontCache.get(fontname);
        if (typeface == null) {
            try {
                typeface = Typeface.createFromAsset(context.getAssets(), fontname);
            } catch (Exception e) {
                typeface = Typeface.createFromAsset(context.getAssets(), "fonts/Roboto-Regular.ttf");
            }
            fontCache.put(fontname, typeface);
        }
        return typeface;
    }
}

答案 2 :(得分:0)

传递正确的上下文: 改变这个

Typeface face2 = Typeface.createFromAsset(textview.getContext().getAssets(), "fonts/Israr.ttf");

Typeface face2 = Typeface.createFromAsset(PlayerMainScreen.this.getAssets(), "fonts/Israr.ttf");

答案 3 :(得分:-1)

这是因为您在适配器外部设置了textview字体。 要为适配器项设置Typeface,可以覆盖适配器的getView()方法:

ArrayAdapter arrayAdapter = new ArrayAdapter<String>(this, R.layout.fragment_player_main_screen, R.id.textViewsawtyat1, playerList.get(0)){
  @NonNull
  @Override
  public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
    TextView textView = (TextView) super.getView(position, convertView, parent);
    Typeface mface = Typeface.createFromAsset(textView.getContext().getAssets(), "fonts/Isra.ttf");
    textView.setTypeface(face);
    return textView;
  }
};